Scandit / scandit-capacitor-datacapture-core

0 stars 3 forks source link

Karma tests are failing #4

Closed bettysteger closed 1 year ago

bettysteger commented 1 year ago

The barcode scanner works on my Android device, but our Karma tests are failing. I am using Capacitor v4 and scandit-capacitor-datacapture-core 6.16.0-beta.1. This is the Error:

Chrome Headless 109.0.5412.0 (Mac OS 10.15.7) ERROR: 'Unhandled Promise rejection:', 'Cannot read properties of undefined (reading 'getDefaults')', '; Zone:', '<root>', '; Task:', null, '; Value:', TypeError: Cannot read properties of undefined (reading 'getDefaults')
TypeError: Cannot read properties of undefined (reading 'getDefaults')
    at executor (http://localhost:9876/_karma_webpack_/webpack:/node_modules/scandit-capacitor-datacapture-core/dist/esm/ts/Capacitor/Capacitor.js:31:90)
    at new ZoneAwarePromise (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1354:25)
    at Module.6027 (http://localhost:9876/_karma_webpack_/webpack:/node_modules/scandit-capacitor-datacapture-core/dist/esm/ts/Capacitor/Capacitor.js:31:28)
    at __webpack_require__ (http://localhost:9876/_karma_webpack_/webpack:/webpack/bootstrap:19:1)
    at Module.9439 (http://localhost:9876/_karma_webpack_/vendor.js:50719:81)

I am using ionic + Angular and use the plugin like this:

// @see https://docs.scandit.com/data-capture-sdk/capacitor/index.html
// @see https://support.scandit.com/hc/en-us/articles/360014254779-Cordova-Using-Cordova-6-x-with-Ionic
import { Injectable, NgZone } from '@angular/core';
import { environment } from '@env/environment';
import { Actions, ofActionCompleted, Store } from '@ngxs/store';
import { ScanditCaptureCorePlugin } from 'scandit-capacitor-datacapture-core';
import 'scandit-capacitor-datacapture-barcode';

import { InitDeviceInfos } from 'core/state/device/device.actions';
import { DeviceState } from 'core/state/device/device.state';
import { DidScanCode, OpenScanner } from 'containers/scandit-scanner/state/scanner.actions';

@Injectable({
  providedIn: 'root',
})
export class ScanditScannerService {
  private scandit;
  public barcodeCapture;
  public session;
  private context;
  private camera;
  private settings;
  private view;
  private overlay;

  constructor(private _store: Store, private _actions$: Actions, private zone: NgZone) {
    this._actions$.pipe(ofActionCompleted(InitDeviceInfos)).subscribe(async () => {
      const isRealDevice = this._store.selectSnapshot<boolean>(DeviceState.isRealDevice);
      if (!isRealDevice) {
        return;
      }
    });
  }

  public async openScanner(): Promise<void> {
    if (this.barcodeCapture) {
      this.view.connectToElement(document.getElementById('scanner'));
      this.resumeScanner();
      return;
    }
    this.scandit = await ScanditCaptureCorePlugin.initializePlugins();

    this.context = this.scandit.DataCaptureContext.forLicenseKey(environment.scandit.license_key);
    this.camera = this.scandit.Camera.default;
    this.context.setFrameSource(this.camera);

    this.settings = new this.scandit.BarcodeCaptureSettings();

    this.settings.enableSymbologies([
      this.scandit.Symbology.EAN13UPCA,
      this.scandit.Symbology.EAN8,
      this.scandit.Symbology.UPCE,
      this.scandit.Symbology.QR,
      this.scandit.Symbology.DataMatrix,
      this.scandit.Symbology.Code39,
      this.scandit.Symbology.Code128,
      this.scandit.Symbology.InterleavedTwoOfFive,
    ]);
    this.settings.codeDuplicateFilter = -1;
    this.barcodeCapture = this.scandit.BarcodeCapture.forContext(this.context, this.settings);
    this.barcodeCapture.applySettings(this.settings);
    this.barcodeCapture.addListener({
      didScan: (_, session) => this._onScan(session),
    });
    this.view = this.scandit.DataCaptureView.forContext(this.context);
    this.view.connectToElement(document.getElementById('scanner'));
    this.overlay = this.scandit.BarcodeCaptureOverlay.withBarcodeCaptureForView(this.barcodeCapture, this.view);
    this.overlay.viewfinder = new this.scandit.RectangularViewfinder();
    this.camera.switchToDesiredState(this.scandit.FrameSourceState.On);
    this.barcodeCapture.isEnabled = true;
  }

  public resumeScanner(): void {
    this.barcodeCapture.isEnabled = true;
    this.camera.switchToDesiredState(this.scandit.FrameSourceState.On);
  }
  public closeScanner(): void {
    this.barcodeCapture.isEnabled = false;
    this.camera.switchToDesiredState(this.scandit.FrameSourceState.Standby);
  }

  private _onScan(session) {
    this.closeScanner();

    if (
      session &&
      session.newlyRecognizedBarcodes &&
      session.newlyRecognizedBarcodes.length &&
      session.newlyRecognizedBarcodes[0].data
    ) {
      const code = session.newlyRecognizedBarcodes[0].data;
      const type = this._extractType(session);

      this._dispatchDidScan(code, type);
    } else {
      console.log('Could not access scanned code.');
    }
  }

  private _extractType(session) {
    if (!session.newlyRecognizedBarcodes[0].symbology) {
      return 'UNKNOWN';
    }

    return session.newlyRecognizedBarcodes[0].symbology
      .toString()
      .toUpperCase()
      .replace('-', '_');
  }

  private _dispatchDidScan(code: string, type) {
    console.log(`Dispatching barcode: "${code}" of barcodeType: "${type}"`);

    this._store.dispatch(
      new DidScanCode({
        barcode: code,
        barcodeType: type,
      }),
    );
  }
}

I do not have a specific test for this scanner service, it just fails on this simple test where the service is injected:

import { TestBed } from '@angular/core/testing';

import { ScanditScannerService } from './scandit-scanner.service';
import { NgxsModule } from '@ngxs/store';

describe('ScannerService', () => {
  let service: ScanditScannerService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [NgxsModule.forRoot()],
    });
    service = TestBed.inject(ScanditScannerService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});
ScanditSupport commented 1 year ago

Hi @bettysteger,

Thank you for your message.

We are currently looking into testing behaviour and plan to address it as quickly as possible in an upcoming version of our SDK, depending on the QA process.

If you want us to inform you about the progress, please get in contact with us directly via: Submit a request – Frequently Asked Questions (FAQ)