UNPKG

scandit-sdk

Version:

Scandit Barcode Scanner SDK for the Web

367 lines (347 loc) 16.4 kB
/* tslint:disable:no-implicit-dependencies no-any */ /** * BarcodePickerGui tests */ import test from "ava"; import * as sinon from "sinon"; import { BarcodePicker, BrowserHelper, ImageSettings, Scanner, ScanSettings } from ".."; import { BarcodePickerGui } from "./barcodePickerGui"; const defaultBarcodePickerGuiOptions: any = { scanner: sinon.createStubInstance(Scanner, { getScanSettings: new ScanSettings() }), originElement: document.createElement("div"), singleImageMode: false, scanningPaused: false, visible: true, guiStyle: BarcodePicker.GuiStyle.LASER, videoFit: BarcodePicker.ObjectFit.CONTAIN, laserArea: undefined, viewfinderArea: undefined, cameraUploadCallback: () => { return Promise.resolve(); }, hideLogo: false }; function defineConfigurableProperty(object: any, property: string, value: any): void { Object.defineProperty(object, property, { value, configurable: true }); } test("constructor & destroy", async t => { let gui: BarcodePickerGui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, visible: false }); gui.destroy(); t.pass(); BrowserHelper.userAgentInfo.setUA( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) " + "AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15" ); gui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, singleImageMode: true, scanningPaused: true, guiStyle: BarcodePicker.GuiStyle.VIEWFINDER, videoFit: BarcodePicker.ObjectFit.COVER, hideLogo: true }); gui.destroy(); t.pass(); }); test("constructor visible option & isVisible & setVisible", async t => { let gui: BarcodePickerGui = new BarcodePickerGui(defaultBarcodePickerGuiOptions); t.true(gui.isVisible()); gui.setVisible(false); t.false(gui.isVisible()); gui.setVisible(true); t.true(gui.isVisible()); gui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, visible: false, guiStyle: BarcodePicker.GuiStyle.VIEWFINDER }); t.false(gui.isVisible()); gui.setVisible(true); t.true(gui.isVisible()); }); test("constructor guiStyle option & setGuiStyle", async t => { let gui: BarcodePickerGui = new BarcodePickerGui(defaultBarcodePickerGuiOptions); t.is((<any>gui).guiStyle, BarcodePicker.GuiStyle.LASER); t.false((<any>gui).laserContainerElement.classList.contains(BarcodePickerGui.hiddenClassName)); t.true((<any>gui).viewfinderElement.classList.contains(BarcodePickerGui.hiddenClassName)); gui.setGuiStyle(BarcodePicker.GuiStyle.VIEWFINDER); t.is((<any>gui).guiStyle, BarcodePicker.GuiStyle.VIEWFINDER); t.true((<any>gui).laserContainerElement.classList.contains(BarcodePickerGui.hiddenClassName)); t.false((<any>gui).viewfinderElement.classList.contains(BarcodePickerGui.hiddenClassName)); gui.setGuiStyle(BarcodePicker.GuiStyle.NONE); t.is((<any>gui).guiStyle, BarcodePicker.GuiStyle.NONE); t.true((<any>gui).laserContainerElement.classList.contains(BarcodePickerGui.hiddenClassName)); t.true((<any>gui).viewfinderElement.classList.contains(BarcodePickerGui.hiddenClassName)); gui.setGuiStyle(BarcodePicker.GuiStyle.VIEWFINDER); t.is((<any>gui).guiStyle, BarcodePicker.GuiStyle.VIEWFINDER); gui.setGuiStyle(<BarcodePicker.GuiStyle>"invalid"); t.is((<any>gui).guiStyle, BarcodePicker.GuiStyle.NONE); t.true((<any>gui).laserContainerElement.classList.contains(BarcodePickerGui.hiddenClassName)); t.true((<any>gui).viewfinderElement.classList.contains(BarcodePickerGui.hiddenClassName)); gui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, singleImageMode: true }); gui.flashGUI(); t.is((<any>gui).guiStyle, BarcodePicker.GuiStyle.NONE); gui.setGuiStyle(BarcodePicker.GuiStyle.LASER); t.is((<any>gui).guiStyle, BarcodePicker.GuiStyle.NONE); }); test("reassignOriginElement", async t => { const originElement1: HTMLDivElement = document.createElement("div"); const originElement2: HTMLDivElement = document.createElement("div"); const gui: BarcodePickerGui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, originElement: originElement1 }); t.deepEqual((<any>gui).originElement, originElement1); gui.reassignOriginElement(originElement2); t.deepEqual((<any>gui).originElement, originElement2); gui.setVisible(false); gui.reassignOriginElement(originElement1); t.deepEqual((<any>gui).originElement, originElement1); t.true(originElement1.classList.contains(BarcodePickerGui.hiddenClassName)); t.false(originElement2.classList.contains(BarcodePickerGui.hiddenClassName)); gui.reassignOriginElement(originElement2); t.deepEqual((<any>gui).originElement, originElement2); t.false(originElement1.classList.contains(BarcodePickerGui.hiddenClassName)); t.true(originElement2.classList.contains(BarcodePickerGui.hiddenClassName)); }); test("flashGUI", async t => { const gui: BarcodePickerGui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, guiStyle: BarcodePicker.GuiStyle.NONE }); const flashLaserSpy: sinon.SinonSpy = sinon.spy(<any>gui, "flashLaser"); const flashViewfinderSpy: sinon.SinonSpy = sinon.spy(<any>gui, "flashViewfinder"); t.is(flashLaserSpy.callCount, 0); t.is(flashViewfinderSpy.callCount, 0); gui.flashGUI(); t.is(flashLaserSpy.callCount, 0); t.is(flashViewfinderSpy.callCount, 0); gui.setGuiStyle(BarcodePicker.GuiStyle.LASER); gui.flashGUI(); t.is(flashLaserSpy.callCount, 1); t.is(flashViewfinderSpy.callCount, 0); gui.setGuiStyle(BarcodePicker.GuiStyle.VIEWFINDER); gui.flashGUI(); t.is(flashLaserSpy.callCount, 1); t.is(flashViewfinderSpy.callCount, 1); }); test("setCameraSwitcherVisible", async t => { const gui: BarcodePickerGui = new BarcodePickerGui(defaultBarcodePickerGuiOptions); gui.setCameraSwitcherVisible(false); t.true((<any>gui).cameraSwitcherElement.classList.contains(BarcodePickerGui.hiddenClassName)); gui.setCameraSwitcherVisible(true); t.false((<any>gui).cameraSwitcherElement.classList.contains(BarcodePickerGui.hiddenClassName)); }); test("setTorchTogglerVisible", async t => { const gui: BarcodePickerGui = new BarcodePickerGui(defaultBarcodePickerGuiOptions); gui.setTorchTogglerVisible(false); t.true((<any>gui).torchTogglerElement.classList.contains(BarcodePickerGui.hiddenClassName)); gui.setTorchTogglerVisible(true); t.false((<any>gui).torchTogglerElement.classList.contains(BarcodePickerGui.hiddenClassName)); }); test("resize video", async t => { const scanSettings: ScanSettings = new ScanSettings(); const scanner: sinon.SinonStubbedInstance<Scanner> = sinon.createStubInstance(Scanner, { getScanSettings: scanSettings }); const originElement: HTMLDivElement = document.createElement("div"); const gui: BarcodePickerGui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, originElement, scanner: <Scanner>(<unknown>scanner) }); // No video dimensions available yet t.is((<any>gui).parentElement.style.maxWidth, ""); t.is((<any>gui).parentElement.style.maxHeight, ""); defineConfigurableProperty(originElement, "clientWidth", 100); defineConfigurableProperty(originElement, "clientHeight", 100); defineConfigurableProperty(gui.videoElement, "videoWidth", 100); defineConfigurableProperty(gui.videoElement, "videoHeight", 100); gui.setVideoFit(BarcodePicker.ObjectFit.CONTAIN); t.is((<any>gui).parentElement.style.maxWidth, "100px"); t.is((<any>gui).parentElement.style.maxHeight, "100px"); defineConfigurableProperty(originElement, "clientWidth", 100); defineConfigurableProperty(originElement, "clientHeight", 50); (<any>gui).resize(); t.is((<any>gui).parentElement.style.maxWidth, "50px"); t.is((<any>gui).parentElement.style.maxHeight, "50px"); defineConfigurableProperty(originElement, "clientWidth", 25); defineConfigurableProperty(originElement, "clientHeight", 100); (<any>gui).resize(); t.is((<any>gui).parentElement.style.maxWidth, "25px"); t.is((<any>gui).parentElement.style.maxHeight, "25px"); defineConfigurableProperty(originElement, "clientWidth", 100); defineConfigurableProperty(originElement, "clientHeight", 100); (<any>gui).resize(); t.is((<any>gui).parentElement.style.maxWidth, "100px"); t.is((<any>gui).parentElement.style.maxHeight, "100px"); gui.setVideoFit(BarcodePicker.ObjectFit.COVER); t.deepEqual(scanSettings.getBaseSearchArea(), { x: 0, y: 0, width: 1, height: 1 }); t.is((<any>gui).parentElement.style.maxWidth, ""); t.is((<any>gui).parentElement.style.maxHeight, ""); defineConfigurableProperty(gui.videoElement, "videoWidth", 200); defineConfigurableProperty(gui.videoElement, "videoHeight", 100); gui.setVideoFit(BarcodePicker.ObjectFit.CONTAIN); t.is((<any>gui).parentElement.style.maxWidth, "100px"); t.is((<any>gui).parentElement.style.maxHeight, "50px"); gui.setVideoFit(BarcodePicker.ObjectFit.COVER); t.deepEqual(scanSettings.getBaseSearchArea(), { x: 0.25, y: 0, width: 0.5, height: 1 }); t.is((<any>gui).parentElement.style.maxWidth, ""); t.is((<any>gui).parentElement.style.maxHeight, ""); defineConfigurableProperty(gui.videoElement, "videoWidth", 100); defineConfigurableProperty(gui.videoElement, "videoHeight", 200); gui.setVideoFit(BarcodePicker.ObjectFit.CONTAIN); t.is((<any>gui).parentElement.style.maxWidth, "50px"); t.is((<any>gui).parentElement.style.maxHeight, "100px"); gui.setVideoFit(BarcodePicker.ObjectFit.COVER); t.deepEqual(scanSettings.getBaseSearchArea(), { x: 0, y: 0.25, width: 1, height: 0.5 }); t.is((<any>gui).parentElement.style.maxWidth, ""); t.is((<any>gui).parentElement.style.maxHeight, ""); }); test("resize singleImage", async t => { const originElement: HTMLDivElement = document.createElement("div"); const gui: BarcodePickerGui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, originElement, singleImageMode: true }); t.is((<any>gui).cameraUploadLabelElement.style.transform, "scale(0)"); defineConfigurableProperty(originElement, "clientWidth", 500); defineConfigurableProperty(originElement, "clientHeight", 300); (<any>gui).resize(); t.is((<any>gui).cameraUploadLabelElement.style.transform, "scale(1)"); defineConfigurableProperty(originElement, "clientWidth", 1000); defineConfigurableProperty(originElement, "clientHeight", 600); (<any>gui).resize(); t.is((<any>gui).cameraUploadLabelElement.style.transform, "scale(1)"); defineConfigurableProperty(originElement, "clientWidth", 250); (<any>gui).resize(); t.is((<any>gui).cameraUploadLabelElement.style.transform, "scale(0.5)"); defineConfigurableProperty(originElement, "clientHeight", 30); (<any>gui).resize(); t.is((<any>gui).cameraUploadLabelElement.style.transform, "scale(0.1)"); defineConfigurableProperty(originElement, "clientWidth", 5); (<any>gui).resize(); t.is((<any>gui).cameraUploadLabelElement.style.transform, "scale(0.01)"); }); // tslint:disable-next-line:max-func-body-length test("cameraUploadFile", async t => { function base64StringtoPngFile(base64String: string): File { const byteString: string = atob(base64String); const byteArray: Uint8ClampedArray = new Uint8ClampedArray(byteString.length); for (let i: number = 0; i < byteString.length; i++) { byteArray[i] = byteString.charCodeAt(i); } return new File([byteArray], "/test", { type: "image/png" }); } let imageSettings: ImageSettings | undefined; const scanner: sinon.SinonStubbedInstance<Scanner> = sinon.createStubInstance(Scanner, { getScanSettings: new ScanSettings(), getImageSettings: <sinon.SinonStub<[], ImageSettings | undefined>>(<unknown>sinon.stub().callsFake((): | ImageSettings | undefined => { return imageSettings; })), applyImageSettings: <sinon.SinonStub<[ImageSettings], Scanner>>(<unknown>sinon.stub().callsFake( (newImageSettings: ImageSettings): Scanner => { imageSettings = newImageSettings; return <Scanner>(<unknown>scanner); } )) }); const gui: BarcodePickerGui = new BarcodePickerGui({ ...defaultBarcodePickerGuiOptions, scanner: <Scanner>(<unknown>scanner), singleImageMode: true }); Object.defineProperty(Image.prototype, "onprogress", { set: (value: (event: ProgressEvent) => void) => { value( new ProgressEvent("progress", { loaded: 0, total: 100, lengthComputable: true }) ); } }); (<any>gui).cameraUploadFile(); let fileList: any = [ // 4x4 white image base64StringtoPngFile( "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAQAAAAD+Fb1AAAAEElEQVR42mP8/58BDBhxMwCn1gf9tpc9tgAAAABJRU5ErkJggg==" ) ]; defineConfigurableProperty((<any>gui).cameraUploadInputElement, "files", fileList); (<any>gui).cameraUploadFile(); await new Promise(resolve => { setTimeout(resolve, 200); }); t.deepEqual(scanner.getImageSettings(), { width: 4, height: 4, format: ImageSettings.Format.RGBA_8U }); fileList = [ // 1600x100 white image base64StringtoPngFile( // tslint:disable-next-line:max-line-length "iVBORw0KGgoAAAANSUhEUgAABkAAAABkCAQAAAB06DQ2AAABz0lEQVR42u3XQREAAAgDINc/9Czh+YIWpB0AAIAXERAAAEBAAAAAAQEAABAQAABAQAAAAAQEAAAQEAAAQEAAAAAEBAAAEBAAAAABAQAABAQAABAQAAAAAQEAAAQEAABAQAAAAAEBAAAEBAAAQEAAAAABAQAAEBAAAEBAAAAAAQEAABAQAABAQAAAAAQEAAAQEAAAQEAAAAAEBAAAEBAAAAABAQAABAQAAEBAAAAAAQEAAAQEAABAQAAAAAEBAAAQEAAAQEAAAAABAQAAEBAAAEBAAAAABAQAABAQAABAQAAAAAQEAAAQEAAAAAEBAAAEBAAAEBAAAAABAQAABAQAAEBAAAAAAQEAAAQEAABAQAAAAAEBAAAQEAAAQEAAAAAEBAAAEBAAAEBAAAAABAQAABAQAAAAAQEAAAQEAAAQEAAAAAEBAAAEBAAAQEAAAAABAQAABAQAAEBAAAAAAQEAABAQAABAQAAAAAEBAAAQEAAAQEAAAAAEBAAAEBAAAEBAAAAABAQAABAQAAAAAQEAAAQEAAAQEAEBAAAEBAAAEBAAAAABAQAABAQAAEBAAAAAAQEAAAQEAABAQAAAAAEBAAAQEAAAQEAAAAABAQAAuLNeC8edzcWfbQAAAABJRU5ErkJggg==" ) ]; defineConfigurableProperty((<any>gui).cameraUploadInputElement, "files", fileList); (<any>gui).cameraUploadFile(); await new Promise(resolve => { setTimeout(resolve, 200); }); t.deepEqual(scanner.getImageSettings(), { width: 1440, height: 90, format: ImageSettings.Format.RGBA_8U }); fileList = [ // 100x1600 white image base64StringtoPngFile( // tslint:disable-next-line:max-line-length "iVBORw0KGgoAAAANSUhEUgAAAGQAAAZACAQAAAAlBi/FAAAE+UlEQVR42u3PAQ0AAAgDIN8/9M2hgwaknRciIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJy2QLJ03p1wqRRzwAAAABJRU5ErkJggg==" ) ]; defineConfigurableProperty((<any>gui).cameraUploadInputElement, "files", fileList); (<any>gui).cameraUploadFile(); await new Promise(resolve => { setTimeout(resolve, 200); }); t.deepEqual(scanner.getImageSettings(), { width: 90, height: 1440, format: ImageSettings.Format.RGBA_8U }); });