diff options
Diffstat (limited to 'testing/web-platform/tests/shape-detection')
25 files changed, 1326 insertions, 0 deletions
diff --git a/testing/web-platform/tests/shape-detection/META.yml b/testing/web-platform/tests/shape-detection/META.yml new file mode 100644 index 0000000000..7754624047 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/META.yml @@ -0,0 +1,3 @@ +spec: https://wicg.github.io/shape-detection-api/ +suggested_reviewers: + - yellowdoge diff --git a/testing/web-platform/tests/shape-detection/README.md b/testing/web-platform/tests/shape-detection/README.md new file mode 100644 index 0000000000..624b021336 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/README.md @@ -0,0 +1,63 @@ +The `shapedetection-helpers.js` tests require implementations of +the `FaceDetectionTest`, `BarcodeDetectionTest` and `TextDetectionTest` +interfaces, which should emulate platform shape detection backends. + +The `FaceDetectionTest` interface is defined as: + +``` + class FaceDetectionTest { + async initialize(); // Sets up the testing environment. + async reset(); // Frees the resources. + MockFaceDetectionProvider(); //Returns `MockFaceDetectionProvider` interface. + }; + + class MockFaceDetectionProvider { + getFrameData(); //Gets frame data of detection result. + getMaxDetectedFaces(); //Gets value of `maxDetectedFaces` in `FaceDetector` constructor + getFastMode(); //Gets value of `fastMode` in `FaceDetector` constructor + }; +``` + +The Chromium implementation of the `FaceDetectionTest` interface is located in +[mock-facedetection.js](../resources/chromium/mock-facedetection.js). + +The `BarcodeDetectionTest` interface is defined as: + +``` + class BarcodeDetectionTest { + async initialize(); // Sets up the testing environment. + async reset(); // Frees the resources. + MockBarcodeDetectionProvider(); //Returns `MockBarcodeDetectionProvider` interface. + }; + + class MockBarcodeDetectionProvider { + async enumerateSupportedFormats(); //Enumerates supported formats + getFrameData(); //Gets frame data of detection result. + getFormats(); //Gets value of `formats` in `BarcodeDetector` constructor + simulateNoImplementation(); // simulate a 'no implementation available' case + }; +``` + +The Chromium implementation of the `BarcodeDetectionTest` interface is located in +[mock-barcodedetection.js](../resources/chromium/mock-barcodedetection.js). + +The `TextDetectionTest` interface is defined as: + +``` + class TextDetectionTest { + async initialize(); // Sets up the testing environment. + async reset(); // Frees the resources. + MockTextDetection(); //Returns `MockTextDetection` interface. + }; + + class MockTextDetection { + getFrameData(); //Gets frame data of detection result. + }; +``` + +The Chromium implementation of the `TextDetectionTest` interface is located in +[mock-textdetection.js](../resources/chromium/mock-textdetection.js). + +Other browser vendors should provide their own implementations of +the `FaceDetectionTest`, `BarcodeDetectionTest` and `TextDetectionTest` +interfaces. diff --git a/testing/web-platform/tests/shape-detection/detected-boundingBox-read-only.https.html b/testing/web-platform/tests/shape-detection/detected-boundingBox-read-only.https.html new file mode 100644 index 0000000000..dcf379b97a --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detected-boundingBox-read-only.https.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// These tests verify that detected{Face, Barcode, Text}'s boundingBox +// should be DOMRectReadOnly. +const imageDataTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + name: "Face - detectedFace.boundingBox should be DOMRectReadOnly" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + name: "Barcode - detectedBarcode.boundingBox should be DOMRectReadOnly" + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + name: "Text - detectedText.boundingBox should be DOMRectReadOnly" + } + ]; + +for (let imageDataTest of imageDataTests) { + detection_test(imageDataTest.mockTestName, async t => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = "/images/green-16x16.png"; + await imgWatcher.wait_for("load"); + + const canvas = document.createElement("canvas"); + canvas.getContext("2d").drawImage(img, 0, 0); + + const detector = imageDataTest.createDetector(); + const detectionResult = await detector.detect(canvas.getContext("2d") + .getImageData(0, 0, canvas.width, canvas.height)); + CheckDetectedReadOnlyBoundingBoxes(detectionResult); + }, imageDataTest.name); +} + +function CheckDetectedReadOnlyBoundingBoxes(detectedObjects) { + const properties = + ['x', 'y', 'width', 'height', 'top', 'right', 'bottom', 'left']; + + detectedObjects.forEach(detectedObject => { + properties.forEach(property => { + assert_readonly(detectedObject.boundingBox, property); + }); + }); +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/detected-postMessage.https.html b/testing/web-platform/tests/shape-detection/detected-postMessage.https.html new file mode 100644 index 0000000000..8066984b26 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detected-postMessage.https.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// These tests verify that Detected{Face, Barcode, Text} can be passed to +// postMessage(). +const postMessageTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - DetectedFace can be passed to postMessage()" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - DetectedBarcode can be passed to postMessage()" + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - DetectedText can be passed to postMessage()", + }, + ]; + +for (let postMessageTest of postMessageTests) { + detection_test(postMessageTest.mockTestName, async t => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = "/images/green-16x16.png"; + await imgWatcher.wait_for("load"); + + const canvas = document.createElement("canvas"); + canvas.getContext("2d").drawImage(img, 0, 0); + + const detector = postMessageTest.createDetector(); + const detectionResult = await detector.detect(canvas.getContext("2d") + .getImageData(0, 0, canvas.width, canvas.height)); + + const msgWatcher = new EventWatcher(t, window, ['message']); + window.postMessage(detectionResult); + const evt = await msgWatcher.wait_for('message'); + postMessageTest.detectionResultTest(evt.data) + }, postMessageTest.name); +} + +function FaceDetectorDetectionResultTest(detectionResult) { + assert_equals(detectionResult.length, 3, "Number of faces"); + assert_equals(detectionResult[0].landmarks.length, 2, "Number of landmarks"); + assert_object_equals(detectionResult[0].landmarks[0], + {type : 'eye', locations : [{x : 4.0, y : 5.0}]}, + "landmark #1"); + assert_equals(detectionResult[0].landmarks[1].locations.length, 8, + "Number of locations along eye"); + assert_object_equals(detectionResult[1].landmarks[0], + {type : 'nose', locations : [{x : 100.0, y : 50.0}]}, + "landmark #2"); + assert_equals(detectionResult[1].landmarks[1].locations.length, 9, + "Number of locations along nose"); +} + +function BarcodeDetectorDetectionResultTest(detectionResult) { + assert_equals(detectionResult.length, 2, "Number of barcodes"); + assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); + assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); +} + +function TextDetectorDetectionResultTest(detectionResult) { + assert_equals(detectionResult.length, 2, "Number of textBlocks"); + assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1"); + assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2"); + for (let i = 0; i < detectionResult.length; i++) { + assert_equals(detectionResult[i].boundingBox.x, detectionResult[i].cornerPoints[0].x); + assert_equals(detectionResult[i].boundingBox.y, detectionResult[i].cornerPoints[0].y); + assert_equals(detectionResult[i].boundingBox.width, + detectionResult[i].cornerPoints[2].x - detectionResult[i].cornerPoints[3].x); + assert_equals(detectionResult[i].boundingBox.height, + detectionResult[i].cornerPoints[2].y - detectionResult[i].cornerPoints[1].y); + } + +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-Blob.https.window.js b/testing/web-platform/tests/shape-detection/detection-Blob.https.window.js new file mode 100644 index 0000000000..401a9cc72d --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-Blob.https.window.js @@ -0,0 +1,19 @@ +'use strict'; + +promise_test(async (t) => { + const blob = new Blob(['not really a png'], {type: 'image/png'}); + const detector = new FaceDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(blob)); +}, 'FaceDetector.detect() rejects on a Blob'); + +promise_test(async (t) => { + const blob = new Blob(['not really a png'], {type: 'image/png'}); + const detector = new BarcodeDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(blob)); +}, 'BarcodeDetector.detect() rejects on a Blob'); + +promise_test(async (t) => { + const blob = new Blob(['not really a png'], {type: 'image/png'}); + const detector = new TextDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(blob)); +}, 'TextDetector.detect() rejects on a Blob'); diff --git a/testing/web-platform/tests/shape-detection/detection-HTMLCanvasElement.https.html b/testing/web-platform/tests/shape-detection/detection-HTMLCanvasElement.https.html new file mode 100644 index 0000000000..4773bc8a66 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-HTMLCanvasElement.https.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// These tests verify that a Detector's detect() works on an HTMLCanvasElement +// and on an OffscreenCanvas. +const canvasElementTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + createCanvas: () => { return document.createElement("canvas"); }, + pixelFormat: "uint8", + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - detect(HTMLCanvasElement)" + }, + { + createDetector: () => { return new FaceDetector(); }, + createCanvas: () => { return document.createElement("canvas"); }, + pixelFormat: "float16", + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - detect(HTMLCanvasElementF16Format)" + }, + { + createDetector: () => { return new FaceDetector(); }, + createCanvas: () => { return new OffscreenCanvas(300, 150); }, + pixelFormat: "uint8", + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - detect(OffscreenCanvas)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + createCanvas: () => { return document.createElement("canvas"); }, + pixelFormat: "uint8", + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - detect(HTMLCanvasElement)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + createCanvas: () => { return document.createElement("canvas"); }, + pixelFormat: "float16", + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - detect(HTMLCanvasElementF16Format)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + createCanvas: () => { return new OffscreenCanvas(300, 150); }, + pixelFormat: "uint8", + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - detect(OffscreenCanvas)" + }, + { + createDetector: () => { return new TextDetector(); }, + createCanvas: () => { return document.createElement("canvas"); }, + pixelFormat: "uint8", + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - detect(HTMLCanvasElement)" + }, + { + createDetector: () => { return new TextDetector(); }, + createCanvas: () => { return document.createElement("canvas"); }, + pixelFormat: "float16", + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - detect(HTMLCanvasElementF16Format)" + }, + { + createDetector: () => { return new TextDetector(); }, + createCanvas: () => { return new OffscreenCanvas(300, 150); }, + pixelFormat: "uint8", + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - detect(OffscreenCanvas)" + } + ]; + +for (let canvasElementTest of canvasElementTests) { + detection_test(canvasElementTest.mockTestName, async (t, detectionTest) => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = "/images/green-16x16.png"; + await imgWatcher.wait_for("load"); + const canvas = canvasElementTest.createCanvas(); + canvas.getContext( + "2d", { pixelFormat: canvasElementTest.pixelFormat }).drawImage( + img, 0, 0); + + const detector = canvasElementTest.createDetector(); + const detectionResult = await detector.detect(canvas); + canvasElementTest.detectionResultTest(detectionResult, detectionTest); + }, canvasElementTest.name); +} + +function FaceDetectorDetectionResultTest(detectionResult, mockTest) { + const imageReceivedByMock = + mockTest.MockFaceDetectionProvider().getFrameData(); + assert_equals(imageReceivedByMock.byteLength, 180000, "Image length"); + const GREEN_PIXEL = 0xFF00FF00; + assert_equals(imageReceivedByMock[0], GREEN_PIXEL, "Pixel color"); + assert_equals(detectionResult.length, 3, "Number of faces"); +} + +function BarcodeDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of barcodes"); + assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); + assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); +} + +function TextDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of textBlocks"); + assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1"); + assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2"); +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-HTMLImageElement-empty-src.https.html b/testing/web-platform/tests/shape-detection/detection-HTMLImageElement-empty-src.https.html new file mode 100644 index 0000000000..40eee24494 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-HTMLImageElement-empty-src.https.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +// This test verifies *Detector.detect() rejects the promise when fed with +// an HTMLImageElement with an empty 'src'. +const emptyInputTests = [ + { + createDetector: () => { return new FaceDetector(); }, + name: "Face - detect(empty src)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + name: "Barcode - detect(empty src)" + }, + { + createDetector: () => { return new TextDetector(); }, + name: "Text - detect(empty src)" + } +]; + +for (let emptyInputTest of emptyInputTests) { + promise_test(async t => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = ""; + await imgWatcher.wait_for("error"); + + const detector = emptyInputTest.createDetector(); + promise_rejects_dom(t, "InvalidStateError", detector.detect(img)); + }, emptyInputTest.name); +} +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-HTMLImageElement-zero-dimension-image.https.html b/testing/web-platform/tests/shape-detection/detection-HTMLImageElement-zero-dimension-image.https.html new file mode 100644 index 0000000000..621dd4e23f --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-HTMLImageElement-zero-dimension-image.https.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +// This test verifies *Detector.detect() returns an empty list when fed with +// an HTMLImageElement with an image with 0x0 dimensions. +const zeroDimensionsTests = [ + { + createDetector: () => { return new FaceDetector(); }, + name: "Face - detect(0x0)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + name: "Barcode - detect(0x0)" + }, + { + createDetector: () => { return new TextDetector(); }, + name: "Text - detect(0x0)" + } +]; + +for (let zeroDimensionsTest of zeroDimensionsTests) { + promise_test(async t => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = "/images/red-zerosize.svg"; + await imgWatcher.wait_for("load"); + + const detector = zeroDimensionsTest.createDetector(); + const detectionResult = await detector.detect(img); + assert_equals(detectionResult.length, 0); + }, zeroDimensionsTest.name); +} +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-HTMLImageElement.https.html b/testing/web-platform/tests/shape-detection/detection-HTMLImageElement.https.html new file mode 100644 index 0000000000..f3b994c258 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-HTMLImageElement.https.html @@ -0,0 +1,86 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<body> +<img id="img" src="/images/green-16x16.png"/> +</body> +<script> + +// These tests verify that a Detector's detect() works on an HTMLImageElement. +const imageElementTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - detect(HTMLImageElement)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - detect(HTMLImageElement)", + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - detect(HTMLImageElement)" + } + ]; + +for (let imageElementTest of imageElementTests) { + detection_test(imageElementTest.mockTestName, async (t, detectionTest) => { + const img = document.getElementById("img"); + + const detector = imageElementTest.createDetector(); + const detectionResult = await detector.detect(img); + imageElementTest.detectionResultTest(detectionResult, detectionTest); + }, imageElementTest.name); +} + +function FaceDetectorDetectionResultTest(detectionResult, mockTest) { + const imageReceivedByMock = + mockTest.MockFaceDetectionProvider().getFrameData(); + assert_equals(imageReceivedByMock.byteLength, 1024, "Image length"); + const GREEN_PIXEL = 0xFF00FF00; + assert_equals(imageReceivedByMock[0], GREEN_PIXEL, "Pixel color"); + assert_equals(detectionResult.length, 3, "Number of faces"); + assert_equals(detectionResult[0].landmarks.length, 2, "Number of landmarks"); + assert_object_equals(detectionResult[0].landmarks[0], + {type : 'eye', locations : [{x : 4.0, y : 5.0}]}, + "landmark #1"); + assert_equals(detectionResult[0].landmarks[1].locations.length, 8, + "Number of locations along eye"); + assert_object_equals(detectionResult[1].landmarks[0], + {type : 'nose', locations : [{x : 100.0, y : 50.0}]}, + "landmark #2"); + assert_equals(detectionResult[1].landmarks[1].locations.length, 9, + "Number of locations along nose"); +} + +function BarcodeDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of barcodes"); + assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); + assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); +} + +function TextDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of textBlocks"); + assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1"); + assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2"); + for (let i = 0; i < detectionResult.length; i++) { + assert_equals(detectionResult[i].boundingBox.x, detectionResult[i].cornerPoints[0].x); + assert_equals(detectionResult[i].boundingBox.y, detectionResult[i].cornerPoints[0].y); + assert_equals(detectionResult[i].boundingBox.width, + detectionResult[i].cornerPoints[2].x - detectionResult[i].cornerPoints[3].x); + assert_equals(detectionResult[i].boundingBox.height, + detectionResult[i].cornerPoints[2].y - detectionResult[i].cornerPoints[1].y); + } + +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-HTMLVideoElement.https.html b/testing/web-platform/tests/shape-detection/detection-HTMLVideoElement.https.html new file mode 100644 index 0000000000..2ce379bafc --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-HTMLVideoElement.https.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// These tests verify that a Detector's detect() works on an HTMLVideoElement. +const videoElementTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - detect(HTMLVideoElement)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - detect(HTMLVideoElement)" + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - detect(HTMLVideoElement)" + } + ]; + +for (let videoElementTest of videoElementTests) { + detection_test(videoElementTest.mockTestName, async (t, detectionTest) => { + const video = document.createElement("video"); + video.src = "/media/white.webm"; + video.loop = true; + video.autoplay = true; + const videoWatcher = new EventWatcher(t, video, ["play", "error"]); + video.load(); + await videoWatcher.wait_for("play"); + + const detector = videoElementTest.createDetector(); + const detectionResult = await detector.detect(video); + videoElementTest.detectionResultTest(detectionResult, detectionTest); + }, videoElementTest.name); +} + +function FaceDetectorDetectionResultTest(detectionResult, mockTest) { + const imageReceivedByMock = + mockTest.MockFaceDetectionProvider().getFrameData(); + assert_equals(imageReceivedByMock.byteLength, 307200, "Image length"); + assert_equals(detectionResult.length, 3, "Number of faces"); +} + +function BarcodeDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of barcodes"); + assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); + assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); +} + +function TextDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of textBlocks"); + assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1"); + assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2"); +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-ImageBitmap-closed.https.window.js b/testing/web-platform/tests/shape-detection/detection-ImageBitmap-closed.https.window.js new file mode 100644 index 0000000000..80cb373f33 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-ImageBitmap-closed.https.window.js @@ -0,0 +1,44 @@ +'use strict'; + +async function createClosedImageBitmap(t) { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ['load', 'error']); + img.src = '/images/green-16x16.png'; + await imgWatcher.wait_for('load'); + const imageBitmap = await createImageBitmap(img); + imageBitmap.close(); + return imageBitmap; +} + +promise_test(async (t) => { + const imageBitmap = await createClosedImageBitmap(t); + const detector = new FaceDetector(); + try { + await detector.detect(imageBitmap); + assert_unreached(); + } catch (e) { + assert_equals(e.code, DOMException.INVALID_STATE_ERR); + } +}, 'FaceDetector.detect() rejects on a closed ImageBitmap'); + +promise_test(async (t) => { + const imageBitmap = await createClosedImageBitmap(t); + const detector = new BarcodeDetector(); + try { + await detector.detect(imageBitmap); + assert_unreached(); + } catch (e) { + assert_equals(e.code, DOMException.INVALID_STATE_ERR); + } +}, 'BarcodeDetector.detect() rejects on a closed ImageBitmap'); + +promise_test(async (t) => { + const imageBitmap = await createClosedImageBitmap(t); + const detector = new TextDetector(); + try { + await detector.detect(imageBitmap); + assert_unreached(); + } catch (e) { + assert_equals(e.code, DOMException.INVALID_STATE_ERR); + } +}, 'TextDetector.detect() rejects on a closed ImageBitmap'); diff --git a/testing/web-platform/tests/shape-detection/detection-ImageBitmap.https.html b/testing/web-platform/tests/shape-detection/detection-ImageBitmap.https.html new file mode 100644 index 0000000000..b4302c4a51 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-ImageBitmap.https.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// These tests verify that a Detector's detect() works on an ImageBitmap. +const imageBitmapTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - detect(ImageBitmap)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - detect(ImageBitmap)" + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - detect(ImageBitmap)", + } + ]; + +for (let imageBitmapTest of imageBitmapTests) { + detection_test(imageBitmapTest.mockTestName, async (t, detectionTest) => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = "/images/green-16x16.png"; + await imgWatcher.wait_for("load"); + const imageBitmap = await createImageBitmap(img); + + const detector = imageBitmapTest.createDetector(); + const detectionResult = await detector.detect(imageBitmap); + imageBitmapTest.detectionResultTest(detectionResult, detectionTest); + }, imageBitmapTest.name); +} + +function FaceDetectorDetectionResultTest(detectionResult, mockTest) { + const imageReceivedByMock = mockTest.MockFaceDetectionProvider().getFrameData(); + assert_equals(imageReceivedByMock.byteLength, 1024, "Image length"); + const GREEN_PIXEL = 0xFF00FF00; + assert_equals(imageReceivedByMock[0], GREEN_PIXEL, "Pixel color"); + assert_equals(detectionResult.length, 3, "Number of faces"); +} + +function BarcodeDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of barcodes"); + assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); + assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); +} + +function TextDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of textBlocks"); + assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1"); + assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2"); +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-ImageData-detached.https.html b/testing/web-platform/tests/shape-detection/detection-ImageData-detached.https.html new file mode 100644 index 0000000000..b4e31c8656 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-ImageData-detached.https.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + +function detachBuffer(buffer) { + window.postMessage('', '*', [buffer]); +} + +promise_test(async () => { + let data = new ImageData(1024, 1024); + detachBuffer(data.data.buffer); + let detector = new FaceDetector(); + try { + await detector.detect(data); + assert_unreached(); + } catch (e) { + assert_equals(e.code, DOMException.INVALID_STATE_ERR); + } +}, 'FaceDetector.detect() rejects on a detached buffer'); + +promise_test(async () => { + let data = new ImageData(1024, 1024); + detachBuffer(data.data.buffer); + let detector = new BarcodeDetector(); + try { + await detector.detect(data); + assert_unreached(); + } catch (e) { + assert_equals(e.code, DOMException.INVALID_STATE_ERR); + } +}, 'BarcodeDetector.detect() rejects on a detached buffer'); + +promise_test(async () => { + let data = new ImageData(1024, 1024); + detachBuffer(data.data.buffer); + let detector = new TextDetector(); + try { + await detector.detect(data); + assert_unreached(); + } catch (e) { + assert_equals(e.code, DOMException.INVALID_STATE_ERR); + } +}, 'TextDetector.detect() rejects on a detached buffer'); + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-ImageData.https.html b/testing/web-platform/tests/shape-detection/detection-ImageData.https.html new file mode 100644 index 0000000000..330239fdf0 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-ImageData.https.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// These tests verify that a Detector's detect() works on an ImageBitmap. +const imageDataTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + detectionResultTest: FaceDetectorDetectionResultTest, + name: "Face - detect(ImageData)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + detectionResultTest: BarcodeDetectorDetectionResultTest, + name: "Barcode - detect(ImageData)" + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + detectionResultTest: TextDetectorDetectionResultTest, + name: "Text - detect(ImageData)", + } + ]; + +for (let imageDataTest of imageDataTests) { + detection_test(imageDataTest.mockTestName, async (t, detectionTest) => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = "/images/green-16x16.png"; + await imgWatcher.wait_for("load"); + const canvas = document.createElement("canvas"); + canvas.getContext("2d").drawImage(img, 0, 0); + + const detector = imageDataTest.createDetector(); + const detectionResult = await detector.detect(canvas.getContext("2d") + .getImageData(0, 0, canvas.width, canvas.height)); + imageDataTest.detectionResultTest(detectionResult, detectionTest); + }, imageDataTest.name); +} + +function FaceDetectorDetectionResultTest(detectionResult, mockTest) { + const imageReceivedByMock = mockTest.MockFaceDetectionProvider().getFrameData(); + assert_equals(imageReceivedByMock.byteLength, 180000,"Image length"); + const GREEN_PIXEL = 0xFF00FF00; + assert_equals(imageReceivedByMock[0], GREEN_PIXEL, "Pixel color"); + assert_equals(detectionResult.length, 3, "Number of faces"); +} + +function BarcodeDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of barcodes"); + assert_equals(detectionResult[0].rawValue, "cats", "barcode 1"); + assert_equals(detectionResult[0].format, "qr_code", "barcode 1 format"); + assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2"); + assert_equals(detectionResult[1].format, "code_128", "barcode 2 format"); +} + +function TextDetectorDetectionResultTest(detectionResult, mockTest) { + assert_equals(detectionResult.length, 2, "Number of textBlocks"); + assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1"); + assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2"); +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-ImageDataUint16StorageFormat.https.window.js b/testing/web-platform/tests/shape-detection/detection-ImageDataUint16StorageFormat.https.window.js new file mode 100644 index 0000000000..24dd3e597c --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-ImageDataUint16StorageFormat.https.window.js @@ -0,0 +1,41 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js +// META: script=/shape-detection/resources/shapedetection-helpers.js + +const imgUint16 = new ImageData(1024, 1024, {storageFormat: 'uint16'}); + +// These tests verify that a Detector's detect() can process ImageData with +// uint16 storage format. +const imageDataTests = [ + { + createDetector: () => { + return new FaceDetector(); + }, + mockTestName: 'FaceDetectionTest', + name: + 'FaceDetector.detect() can process uint16 storage format ImageData' + }, + { + createDetector: () => { + return new BarcodeDetector(); + }, + mockTestName: 'BarcodeDetectionTest', + name: + 'BarcodeDetector.detect() can process uint16 storage format ImageData' + }, + { + createDetector: () => { + return new TextDetector(); + }, + mockTestName: 'TextDetectionTest', + name: + 'TextDetector.detect() can process uint16 storage format ImageData' + } +]; + +for (let imageDataTest of imageDataTests) { + detection_test(imageDataTest.mockTestName, async () => { + let detector = imageDataTest.createDetector(); + await detector.detect(imgUint16); + }, imageDataTest.name); +} diff --git a/testing/web-platform/tests/shape-detection/detection-SVGImageElement.https.window.js b/testing/web-platform/tests/shape-detection/detection-SVGImageElement.https.window.js new file mode 100644 index 0000000000..22f1629ecc --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-SVGImageElement.https.window.js @@ -0,0 +1,19 @@ +'use strict'; + +promise_test(async (t) => { + const image = document.createElementNS("http://www.w3.org/2000/svg", "image"); + const detector = new FaceDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(image)); +}, 'FaceDetector.detect() rejects on an SVGImageElement'); + +promise_test(async (t) => { + const image = document.createElementNS("http://www.w3.org/2000/svg", "image"); + const detector = new BarcodeDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(image)); +}, 'BarcodeDetector.detect() rejects on an SVGImageElement'); + +promise_test(async (t) => { + const image = document.createElementNS("http://www.w3.org/2000/svg", "image"); + const detector = new TextDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(image)); +}, 'TextDetector.detect() rejects on an SVGImageElement'); diff --git a/testing/web-platform/tests/shape-detection/detection-VideoFrame.https.window.js b/testing/web-platform/tests/shape-detection/detection-VideoFrame.https.window.js new file mode 100644 index 0000000000..601c60bcaf --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-VideoFrame.https.window.js @@ -0,0 +1,24 @@ +'use strict'; + +function createVideoFrame() { + const canvas = document.createElement('canvas'); + return new VideoFrame(canvas, {timestamp: 0}); +} + +promise_test(async (t) => { + const frame = createVideoFrame(); + const detector = new FaceDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(frame)); +}, 'FaceDetector.detect() rejects on a VideoFrame'); + +promise_test(async (t) => { + const frame = createVideoFrame(); + const detector = new BarcodeDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(frame)); +}, 'BarcodeDetector.detect() rejects on a VideoFrame'); + +promise_test(async (t) => { + const frame = createVideoFrame(); + const detector = new TextDetector(); + await promise_rejects_dom(t, 'NotSupportedError', detector.detect(frame)); +}, 'TextDetector.detect() rejects on a VideoFrame'); diff --git a/testing/web-platform/tests/shape-detection/detection-getSupportedFormats.https.html b/testing/web-platform/tests/shape-detection/detection-getSupportedFormats.https.html new file mode 100644 index 0000000000..0b4b223369 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-getSupportedFormats.https.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<link rel="help" href="https://wicg.github.io/shape-detection-api/#dom-barcodedetector-getsupportedformats"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +detection_test('BarcodeDetectionTest', async t => { + const result = await BarcodeDetector.getSupportedFormats(); + assert_equals(result.length, 3, 'Number of supported formats'); + assert_equals(result[0], 'aztec', 'format 1'); + assert_equals(result[1], 'data_matrix', 'format 2'); + assert_equals(result[2], 'qr_code', 'format 3'); +}, 'get supported barcode formats'); + +detection_test('BarcodeDetectionTest', async (t, detectionTest) => { + // Disable built-in support for barcode detection to test fallback handling. + detectionTest.MockBarcodeDetectionProvider().simulateNoImplementation(); + + const result = await BarcodeDetector.getSupportedFormats(); + assert_equals(result.length, 0, 'result.length'); + +}, 'getSupportedFormats() resolves with empty list when unsupported'); + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-on-worker.https.worker.js b/testing/web-platform/tests/shape-detection/detection-on-worker.https.worker.js new file mode 100644 index 0000000000..3981c6fdc8 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-on-worker.https.worker.js @@ -0,0 +1,54 @@ +importScripts("/resources/testharness.js"); +importScripts("/resources/test-only-api.js"); +importScripts("resources/shapedetection-helpers.js"); + +'use strict'; + +// These tests verify that a Detector's detect() works on an +// ImageBitmap on workers. +const imageBitmapTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + resultSize: 3, // Number of faces + detectorType: "Face" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + resultSize: 2, // Number of barcodes + detectorType: "Barcode" + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + resultSize: 2, // Number of text blocks + detectorType: "Text" + } + ]; + +for (let imageBitmapTest of imageBitmapTests) { + // ImageBitmap is of transferable type and can be sent to and + // tested on worker. + detection_test(imageBitmapTest.mockTestName, async (t, detectionTest) => { + const img = createTestImage(); + const theImageBitmap = await createImageBitmap(img); + const detector = imageBitmapTest.createDetector(); + const detectionResult = await detector.detect(theImageBitmap); + assert_equals(detectionResult.length, imageBitmapTest.resultSize, + `Number of ${imageBitmapTest.detectorType}`); + }, `${imageBitmapTest.detectorType} Detector detect(ImageBitmap) on worker`); +} + +function createTestImage() { + const image = new OffscreenCanvas(100, 50); + const imgctx = image.getContext('2d'); + imgctx.fillStyle = "#F00"; + imgctx.fillRect(0, 0, 2, 2); + imgctx.fillStyle = "#0F0"; + imgctx.fillRect(0, 0, 1, 1); + return image; +} + +done(); diff --git a/testing/web-platform/tests/shape-detection/detection-options.https.html b/testing/web-platform/tests/shape-detection/detection-options.https.html new file mode 100644 index 0000000000..4b79da2a6e --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-options.https.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<body> +<img id="img" src="/images/green-16x16.png"/> +</body> +<script> + +detection_test("FaceDetectionTest", async (t, detectionTest) => { + const img = document.getElementById("img"); + const mock = detectionTest.MockFaceDetectionProvider(); + + const detectorWithDefault = new FaceDetector(); + let faceDetectionResult = await detectorWithDefault.detect(img); + assert_equals(mock.getMaxDetectedFaces(), 10, "default maxDetectedFaces"); + assert_equals(mock.getFastMode(), false, "default maxDetectedFaces"); + + const detectorWithOptions = + new FaceDetector({maxDetectedFaces: 7, fastMode: true}); + faceDetectionResult = await detectorWithOptions.detect(img); + assert_equals(mock.getMaxDetectedFaces(), 7, "maxDetectedFaces"); + assert_equals(mock.getFastMode(), true, "maxDetectedFaces"); +}, "Test that FaceDetectionOptions are correctly propagated"); + +detection_test("BarcodeDetectionTest", async (t, detectionTest) => { + const img = document.getElementById("img"); + const mock = detectionTest.MockBarcodeDetectionProvider(); + + const detectorWithNoOptions = new BarcodeDetector(); + let barcodeDetectionResult = await detectorWithNoOptions.detect(img); + assert_array_equals(mock.getFormats(), [], "formats"); + + const detectorWithOptions = new BarcodeDetector({ + formats: ["code_128", "qr_code"]}); + barcodeDetectionResult = await detectorWithOptions.detect(img); + assert_array_equals( + mock.getFormats(), + [BarcodeFormat.CODE_128, BarcodeFormat.QR_CODE], + "formats"); + + const invalidFormats = [ + [], + ["unknown"], + ["foo", "bar"] + ]; + + invalidFormats.forEach(invalidFormat => { + assert_throws_js(TypeError, () => new BarcodeDetector({formats: invalidFormat})); + }); + +}, "Test that BarcodeDetectorOptions are correctly propagated"); + +</script> diff --git a/testing/web-platform/tests/shape-detection/detection-security-test.https.html b/testing/web-platform/tests/shape-detection/detection-security-test.https.html new file mode 100644 index 0000000000..4d87238dad --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detection-security-test.https.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// Detectors should reject undecodable images with an InvalidStateError. +const badImageTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + name: "Face - detect(broken image)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + name: "Barcode - detect(broken image)" + }, + { + createDetector: () => { return new TextDetector(); }, + name: "Text - detect(broken image)" + } + ]; + +for (let badImageTest of badImageTests) { + // This test verifies that a Detector will reject an undecodable image. + promise_test(async t => { + const img = new Image(); + const error = + await detectOnElementAndExpectError(badImageTest.createDetector, + img, "/images/broken.png"); + assert_equals(error.name, "InvalidStateError"); + }, badImageTest.name); +} + +// Detectors should reject undecodable videos with an InvalidStateError. +const badVideoTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + name: "Face - detect(broken video)" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + name: "Barcode - detect(broken video)" + }, + { + createDetector: () => { return new TextDetector(); }, + name: "Text - detect(broken video)" + } + ]; + +for (let badVideoTest of badVideoTests) { + // This test verifies that a Detector will reject a broken video. + promise_test(async t => { + const video = document.createElement('video'); + const error = + await detectOnElementAndExpectError(badVideoTest.createDetector, + video, "garbage.webm"); + assert_equals(error.name, "InvalidStateError"); + }, badVideoTest.name); +} + +// Returns a Promise that is resolve()d if detect() is rejected. Needs an input +// |element| (e.g. an HTMLImageElement or HTMLVideoElement) and a |url| to load. +function detectOnElementAndExpectError(createDetector, element, url) { + return new Promise((resolve, reject) => { + const tryDetection = async () => { + const detector = createDetector(); + try { + const detectionResult = await detector.detect(element); + reject("Promise should have been rejected."); + } catch (error) { + resolve(error); + } + }; + element.onload = tryDetection; + element.onerror = tryDetection; + element.src = url; + }); +}; + +</script> diff --git a/testing/web-platform/tests/shape-detection/detector-same-object.https.html b/testing/web-platform/tests/shape-detection/detector-same-object.https.html new file mode 100644 index 0000000000..bf7c068041 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/detector-same-object.https.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/shapedetection-helpers.js"></script> +<script> + +// These tests verify that detect()ed Detected{Barcode,Face, Text}'s individual +// fields are [SameObject]. +const imageDataTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + mockTestName: "FaceDetectionTest", + detectionResultTest: CheckDetectedFaceSameObjects, + name: "Face - detect(ImageData), [SameObject]" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + mockTestName: "BarcodeDetectionTest", + detectionResultTest: CheckDetectedBarcodesSameObjects, + name: "Barcode - detect(ImageData), [SameObject]" + }, + { + createDetector: () => { return new TextDetector(); }, + mockTestName: "TextDetectionTest", + detectionResultTest: CheckDetectedTextBlocksSameObjects, + name: "Text - detect(ImageData), [SameObject]", + } + ]; + +for (let imageDataTest of imageDataTests) { + detection_test(imageDataTest.mockTestName, async t => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = "/images/green-16x16.png"; + await imgWatcher.wait_for("load"); + const canvas = document.createElement("canvas"); + canvas.getContext("2d").drawImage(img, 0, 0); + + const detector = imageDataTest.createDetector(); + const detectionResult = await detector.detect(canvas.getContext("2d") + .getImageData(0, 0, canvas.width, canvas.height)); + imageDataTest.detectionResultTest(detectionResult); + }, imageDataTest.name); +} + +function CheckDetectedFaceSameObjects(detectedFaces) { + assert_greater_than(detectedFaces.length, 0, "Number of faces"); + assert_equals(detectedFaces[0].boundingBox, detectedFaces[0].boundingBox); + assert_equals(detectedFaces[0].landmarks, detectedFaces[0].landmarks); +} + +function CheckDetectedBarcodesSameObjects(detectedBarcodes) { + assert_greater_than(detectedBarcodes.length, 0, "Number of barcodes"); + assert_equals(detectedBarcodes[0].rawValue, detectedBarcodes[0].rawValue); + assert_equals(detectedBarcodes[0].boundingBox, detectedBarcodes[0].boundingBox); + assert_equals(detectedBarcodes[0].format, detectedBarcodes[0].format); + assert_equals(detectedBarcodes[0].cornerPoints, detectedBarcodes[0].cornerPoints); +} + +function CheckDetectedTextBlocksSameObjects(detectedTextBlocks) { + assert_greater_than(detectedTextBlocks.length, 0, "Number of textBlocks"); + assert_equals(detectedTextBlocks[0].rawValue, detectedTextBlocks[0].rawValue); + assert_equals(detectedTextBlocks[0].boundingBox, detectedTextBlocks[0].boundingBox); +} + +</script> diff --git a/testing/web-platform/tests/shape-detection/idlharness.https.any.js b/testing/web-platform/tests/shape-detection/idlharness.https.any.js new file mode 100644 index 0000000000..33b5f88f75 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/idlharness.https.any.js @@ -0,0 +1,19 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// See: https://wicg.github.io/shape-detection-api/ + +'use strict'; + +idl_test( + ['shape-detection-api', 'text-detection-api'], + ['dom', 'geometry'], + async idl_array => { + idl_array.add_objects({ + FaceDetector: ['new FaceDetector()'], + BarcodeDetector: ['new BarcodeDetector()'], + TextDetector: ['new TextDetector()'], + }); + } +); diff --git a/testing/web-platform/tests/shape-detection/resources/shapedetection-helpers.js b/testing/web-platform/tests/shape-detection/resources/shapedetection-helpers.js new file mode 100644 index 0000000000..1b4949b8f6 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/resources/shapedetection-helpers.js @@ -0,0 +1,75 @@ +'use strict'; + +// These tests rely on the User Agent providing an implementation of +// platform shape detection 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 import('/resources/chromium/mock-barcodedetection.js'); + await import('/resources/chromium/mock-facedetection.js'); + await import('/resources/chromium/mock-textdetection.js'); +} + +/** + * @param {String} detectionTestName + * name of mock shape detection test interface, + * must be the item of ["FaceDetectionTest", "BarcodeDetectionTest", + * "TextDetectionTest"] +*/ +async function initialize_detection_tests(detectionTestName) { + let detectionTest; + if (typeof document === 'undefined') { + // Use 'self' for workers. + if (typeof self[detectionTestName] === 'undefined') { + // test-only-api.js is already loaded in worker.js + if (isChromiumBased) { + await loadChromiumResources(); + } + } + detectionTest = new self[detectionTestName](); + } else { + if (typeof window[detectionTestName] === '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(); + } + + } + detectionTest = new window[detectionTestName](); + } + await detectionTest.initialize(); + return detectionTest; +} + +function detection_test(detectionTestName, func, name, properties) { + promise_test(async t => { + let detectionTest = await initialize_detection_tests(detectionTestName); + try { + await func(t, detectionTest); + } finally { + await detectionTest.reset(); + }; + }, name, properties); +} + +function getArrayBufferFromBigBuffer(bigBuffer) { + if (bigBuffer.bytes !== undefined) { + return new Uint8Array(bigBuffer.bytes).buffer; + } + return bigBuffer.sharedMemory.bufferHandle.mapBuffer(0, + bigBuffer.sharedMemory.size).buffer; +} diff --git a/testing/web-platform/tests/shape-detection/shapedetection-cross-origin.sub.https.html b/testing/web-platform/tests/shape-detection/shapedetection-cross-origin.sub.https.html new file mode 100644 index 0000000000..c4e3c3fec7 --- /dev/null +++ b/testing/web-platform/tests/shape-detection/shapedetection-cross-origin.sub.https.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> + +// cross-origin resources +const IMAGE_URL = + "https://{{domains[www1]}}:{{ports[https][0]}}/images/green.png"; +const VIDEO_URL = + "https://{{domains[www1]}}:{{ports[https][0]}}/media/white.webm"; + +const crossOriginTests = + [ + { + createDetector: () => { return new FaceDetector(); }, + detectorType: "FaceDetector" + }, + { + createDetector: () => { return new BarcodeDetector(); }, + detectorType: "BarcodeDetector" + }, + { + createDetector: () => { return new TextDetector(); }, + detectorType: "TextDetector" + } + ]; + +for (let crossOriginTest of crossOriginTests) { + + // Verifies that Detector rejects a cross-origin HTMLImageElement. + promise_test(async t => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = IMAGE_URL; + await imgWatcher.wait_for("load"); + const detector = crossOriginTest.createDetector(); + promise_rejects_dom(t, "SecurityError", detector.detect(img)); + }, crossOriginTest.detectorType + + " should reject cross-origin HTMLImageElements with a SecurityError."); + + // Verifies that Detector rejects a cross-origin ImageBitmap. + promise_test(async t => { + const img = new Image(); + const imgWatcher = new EventWatcher(t, img, ["load", "error"]); + img.src = IMAGE_URL; + await imgWatcher.wait_for("load"); + const imgBitmap = await createImageBitmap(img); + const detector = crossOriginTest.createDetector(); + promise_rejects_dom(t, "SecurityError", detector.detect(imgBitmap)); + }, crossOriginTest.detectorType + + " should reject cross-origin ImageBitmaps with a SecurityError."); + + // Verifies that Detector rejects a cross-origin HTMLVideoElement. + promise_test(async t => { + const video = document.createElement('video'); + const videoWatcher = new EventWatcher(t, video, ["loadeddata", "error"]); + video.src = VIDEO_URL; + await videoWatcher.wait_for("loadeddata"); + const detector = crossOriginTest.createDetector(); + promise_rejects_dom(t, "SecurityError", detector.detect(video)); + }, crossOriginTest.detectorType + + " should reject cross-origin HTMLVideoElements with a SecurityError."); + +} + +</script>
\ No newline at end of file |