UNPKG

wdio-ocr-service

Version:

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

145 lines (136 loc) 3.38 kB
import logger from '@wdio/logger' import ocrGetTextPositions from '../utils/ocrGetTextPositions' import { fuzzyFind } from '../utils/fuzzySearch' import { Rectangles, ScreenSize } from '../typings/types' import { SERVICE_NAME } from '../utils/constants' const log = logger(SERVICE_NAME) interface OcrGetElementPositionByTextOptions { androidRectangles?: Rectangles; iOSRectangles?: Rectangles; isTesseractAvailable: boolean; language: string; ocrImagesPath: string; reuseOcr: boolean; screenSize: ScreenSize; text: string; } export interface FuzzyElement { /** * The found item */ item: { /** * the matched string */ text: string; /** * The original position */ originalPosition: Rectangles; /** * The position after DPR check * screenshots for iOS are with DPR * position on the screen for iOS is smaller */ dprPosition: Rectangles; }; /** * Index of the fuzzy logic check */ refIndex: number; /** * Matched score of the fuzzy logic check */ score: number; } interface OcrGetElementPositionByText { /** * the original search value */ searchValue: string; /** * the matched string */ matchedString: string; /** * The original position */ originalPosition: { top: number; left: number; right: number; bottom: number; }, /** * The position after DPR check * screenshots for iOS are with DPR * position on the screen for iOS is smaller */ dprPosition: { top: number; left: number; right: number; bottom: number; }, /** * Matched score of the fuzzy logic check */ score: number; } export default async function ocrGetElementPositionByText( data: OcrGetElementPositionByTextOptions ): Promise<OcrGetElementPositionByText> { const { androidRectangles, iOSRectangles, isTesseractAvailable, language, ocrImagesPath, reuseOcr, screenSize, text, } = data const textPositions = await ocrGetTextPositions({ androidRectangles, iOSRectangles, isTesseractAvailable, language, ocrImagesPath, reuseOcr, screenSize, }) const matches = fuzzyFind({ textArray: textPositions, pattern: text, }) let element let score if (matches.length === 0) { log.warn(`No matches were found based on the word "${text}"`) throw new Error( `InvalidSelectorMatch. Strategy 'ocr' has failed to find word '${text}' in the image` ) } else if (matches.length > 1) { // @ts-ignore matches.sort((a, b) => (a.score > b.score ? 1 : -1)) element = matches[0] as FuzzyElement score = Number(((1-element.score)*100).toFixed(2)) const messageOne = `Multiple matches were found based on the word "${text}".` // @ts-ignore const messageTwo = `The match "${element.item.text}" with score "${score}%" will be used.` log.info(`${messageOne} ${messageTwo}`) } else { element = matches[0] as FuzzyElement score = Number(((1-element.score)*100).toFixed(2)) log.info( `We searched for the word "${text}" and found one match "${element.item.text}" with score "${score}%"` ) } return { searchValue: text, matchedString: element.item.text, originalPosition: element.item.originalPosition, dprPosition: element.item.dprPosition, score, } }