UNPKG

wdio-ocr-service

Version:

A WebdriverIO service that is using Tesseract OCR for Appium Native App tests.

192 lines (175 loc) 6.68 kB
import fs from 'fs' import * as Utils from '../../utils' import createImage from '../../utils/createImage' import * as Tesseract from '../../utils/tesseract' import ocrGetData from '../../utils/ocrGetData' jest.mock('fs') jest.mock('jimp', () => ({ read: jest.fn().mockImplementation(() => ({ contrast: jest.fn(), greyscale: jest.fn(), getBufferAsync: jest.fn().mockReturnValue('getBufferAsync'), })) })) jest.mock('../../utils/createImage', () => jest.fn()) let logger: string[] = [] jest.mock('@wdio/logger', () => jest.fn().mockImplementation(() => ({ info: jest.fn().mockImplementation((...infoArgs) => logger.push(infoArgs)), }))) const globalAny: any = global let getScreenshotSizeSpy: jest.SpyInstance let dateSpy: jest.SpyInstance let getSystemOcrDataSpy: jest.SpyInstance let getNodeOcrDataSpy: jest.SpyInstance describe('utils - ocrGetData', () => { beforeEach(() => { globalAny.driver = { isAndroid: true, isIOS: false, takeScreenshot: jest.fn().mockReturnValue('takeScreenshot') } getScreenshotSizeSpy = jest .spyOn(Utils, 'getScreenshotSize') .mockReturnValue({ height: 400, width: 200 }) fs.writeFileSync = jest.fn() const mockDate = new Date(1466424490000) dateSpy = jest .spyOn(global, 'Date') // @ts-ignore .mockImplementation(() => mockDate) getNodeOcrDataSpy = jest .spyOn(Tesseract, 'getNodeOcrData') getSystemOcrDataSpy = jest .spyOn(Tesseract, 'getSystemOcrData') jest.spyOn(process, 'hrtime').mockReturnValue([0, 0]) }) afterEach(() => { jest.clearAllMocks() logger = [] }) it('should return Node ocrData with default options', async () => { const options = { isTesseractAvailable: false, ocrImagesPath: 'ocrImagesPath', language: 'eng', reuseOcr: false, screenSize: { height: 200, width: 100, } } const ocrData = { text: 'ocrData', lines: [{ text: 'line string', bbox: { left: 1, top: 2, right: 3, bottom: 4 } }], words: [{ text: 'word string', bbox: { left: 5, top: 6, right: 7, bottom: 8 } }], } getNodeOcrDataSpy.mockResolvedValue(ocrData) expect(await ocrGetData(options)).toMatchSnapshot() expect(globalAny.driver.takeScreenshot).toHaveBeenCalledTimes(1) expect(getScreenshotSizeSpy).toHaveBeenCalledTimes(1) expect(dateSpy).toHaveBeenCalled() expect(fs.writeFileSync).toHaveBeenCalledWith('ocrImagesPath/android-1466424490000.png', 'getBufferAsync', { 'encoding': 'base64' }) expect(getSystemOcrDataSpy).not.toHaveBeenCalled() expect(getNodeOcrDataSpy).toHaveBeenCalledWith({ filePath: 'ocrImagesPath/android-1466424490000.png', language: 'eng' }) expect(createImage).toHaveBeenCalledWithSnapshot() expect(logger).toMatchSnapshot() }) it('should return Node ocrData for a cropped Android image', async () => { const options = { androidRectangles: { left: 10, top: 20, right: 30, bottom: 40 }, isTesseractAvailable: false, ocrImagesPath: 'ocrImagesPath', language: 'eng', reuseOcr: false, screenSize: { height: 200, width: 100, } } const ocrData = { text: 'ocrData', lines: [{ text: 'line string', bbox: { left: 100, top: 200, right: 300, bottom: 400 } }], words: [{ text: 'word string', bbox: { left: 500, top: 600, right: 700, bottom: 800 } }], } getNodeOcrDataSpy.mockResolvedValue(ocrData) expect(await ocrGetData(options)).toMatchSnapshot() expect(globalAny.driver.takeScreenshot).toHaveBeenCalledTimes(1) expect(getScreenshotSizeSpy).toHaveBeenCalledTimes(1) expect(fs.writeFileSync).toHaveBeenCalledWith('ocrImagesPath/android-1466424490000.png', 'getBufferAsync', { 'encoding': 'base64' }) // This is the first call for writing the cropped image expect(createImage).toHaveBeenCalledWithSnapshot() }) it('should return Node ocrData for a cropped iOS image', async () => { const options = { iOSRectangles: { left: 10, top: 20, right: 30, bottom: 40 }, isTesseractAvailable: false, ocrImagesPath: 'ocrImagesPath', language: 'eng', reuseOcr: false, screenSize: { height: 200, width: 100, } } const ocrData = { text: 'ocrData', lines: [{ text: 'line string', bbox: { left: 100, top: 200, right: 300, bottom: 400 } }], words: [{ text: 'word string', bbox: { left: 500, top: 600, right: 700, bottom: 800 } }], } globalAny.driver.isAndroid = false globalAny.driver.isIOS = true getNodeOcrDataSpy.mockResolvedValue(ocrData) expect(await ocrGetData(options)).toMatchSnapshot() expect(globalAny.driver.takeScreenshot).toHaveBeenCalledTimes(1) expect(getScreenshotSizeSpy).toHaveBeenCalledTimes(1) expect(fs.writeFileSync).toHaveBeenCalledWith('ocrImagesPath/ios-1466424490000.png', 'getBufferAsync', { 'encoding': 'base64' }) // This is the first call for writing the cropped image expect(createImage).toHaveBeenCalledWithSnapshot() }) it('should return Node ocrData when it needs to re-use stored driver data', async () => { const options = { isTesseractAvailable: false, ocrImagesPath: 'string', language: 'eng', reuseOcr: true, screenSize: { height: 200, width: 100, } } globalAny.driver.ocrData = ['driver.ocrData available'] expect(await ocrGetData(options)).toEqual(['driver.ocrData available']) }) it('should return System ocrData with default options', async () => { const options = { isTesseractAvailable: true, ocrImagesPath: 'ocrImagesPath', language: 'eng', reuseOcr: false, screenSize: { height: 200, width: 100, } } const ocrData = { text: 'ocrData', lines: [{ text: 'line string', bbox: { left: 1, top: 2, right: 3, bottom: 4 } }], words: [{ text: 'word string', bbox: { left: 5, top: 6, right: 7, bottom: 8 } }], } getSystemOcrDataSpy.mockResolvedValue(ocrData) expect(await ocrGetData(options)).toMatchSnapshot() expect(getSystemOcrDataSpy).toHaveBeenCalledWith({ filePath: 'ocrImagesPath/android-1466424490000.png', language: 'eng' }) expect(getNodeOcrDataSpy).not.toHaveBeenCalled() expect(logger).toMatchSnapshot() }) it('should be able to throw an error', async () => { try { // @ts-ignore await ocrGetData({}) // Don't expect it to hit this expect(true).toBe(false) } catch (e) { expect(e.toString()).toBe("Error: TypeError: Cannot read property 'width' of undefined") } }) })