UNPKG

gemini-core

Version:

Utility which contains common modules for gemini and hermione

396 lines (293 loc) 9.62 kB
# gemini-core [![Build Status](https://travis-ci.org/gemini-testing/gemini-core.svg?branch=master)](https://travis-ci.org/gemini-testing/gemini-core) Utility which contains common modules for [gemini](https://github.com/gemini-testing/gemini) and [hermione](https://github.com/gemini-testing/hermione). <!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> **Table of Contents** - [SetsBuilder](#setsbuilder) - [Options](#options) - [Sets](#sets) - [BrowserPool](#browserpool) - [events](#events) - [AsyncEmitter](#asyncemitter) - [utils](#utils) - [promiseUtils](#promiseutils) - [BrowserAgent](#browseragent) - [Errors](#errors) - [CancelledError](#cancellederror) - [Image](#image) - [Methods](#methods) - [crop](#crop) - [getSize](#getsize) - [getRGBA](#getrgba) - [save](#save) - [clear](#clear) - [join](#join) - [Static methods](#static-methods) - [fromBase64](#frombase64) - [RGBToString](#rgbtostring) - [compare](#compare) - [buildDiff](#builddiff) - [Temp](#temp) - [init](#init) - [path](#path) - [serialize](#serialize) - [attach](#attach) - [clientBdridge](#clientbdridge) - [coverageLevel](#coveragelevel) <!-- END doctoc generated TOC please keep comment here to allow auto update --> ### SetsBuilder Creates mapping of test files with browsers in which they should be run and vice versa. Example of usage: ```js const SetsBuilder = require('gemini-core').SetsBuilder; const sets = { desktop: { files: ['desktop/tests/**.js'], ignoreFiles: ['desktop/tests/fixtures/**'], // exclude directories from reading while test finding browsers: ['bro1'], }, touch-phone: { files: ['touch-phone/tests'], browsers: ['bro2'] } }; SetsBuilder .create(sets, {defaultDir: 'default/path'}) // creates setsBuilder using specified tests and options .useSets(['desktop']) // use only the specified sets .useBrowsers(['bro1']) // use only specified browsers .useFiles(['desktop/tests/test.js']) // use only specified files if sets // and files to use are not specified .build('/root', globOpts, ['.js', '.ts']) // builds a collection of sets with paths expanded according // to the project root, glob options and file extensions .then((setCollection) => { setCollection.groupByFile(); // groups all browsers of test-sets by file: // {'desktop/tests/test.js': ['bro1']} setCollection.groupByBrowser(); // groups all files of test-sets by browser: // {'bro': ['desktop/tests/test.js']} }) .done(); ``` ### Options Returns an object with some options. ```js const options = require('gemini-core').config.options; ``` #### Sets ```js const sets = options.sets; // returns a section for configparser with two options – files and browsers. // Default value is an empty set - all: {files: []} ``` ### BrowserPool Example: ```js const BrowserPool = require('gemini-core').BrowserPool; // Some browser realization class Browser { constructor(id) { this.id = 'bro'; // required field this.sessionId = null; // required field } launch() { return doLaunch() .then((sessionId) => this.sessionId = sessionId); } // required method reset() { return doSomeReset(); } quit() { return doQuit(); } } const BrowserManager = { create: (id) => new Browser(id), start: (browser) => browser.launch(), onStart: (browser) => emitter.emitAndWait('sessionStart', browser), onQuit: (browser) => emitter.emitAndWait('sessionEnd', browser), quit: (browser) => browser.quit() }; const config = { forBrowser: (id) => { return { parallelLimit: 1, // maximum number of specific browser sessions executed in parallel sessionUseLimit: 2 // maxiumu number of session reuse (test per session, for example) }; }, getBrowserIds: () => config.getBrowserIds(), system: { parallelLimit: 10 // maximum number of browser sessions at all } }; const pool = BrowserPool.create(BrowserManager, { logNamespace: 'gemini', // prefix for logger. log = require('debug')(`${logNamespace}:pool:...`) config }); return pool.getBrowser('bro'/*, {highPriority: true}*/) .then((bro) => { ... return pool.freeBrowser(bro); }); ``` ### events #### AsyncEmitter Node.js event emitter with promises support. Node.js builtin `EventEmitter` class executes all handlers synchronously without waiting for completion of any async operations that may happen inside. `AsyncEmitter` is the subclass of `EventEmitter` which adds ability to return a promise from event handler and wait until it resolved. Just use `emitAndWait` instead of `emit`: ```js const AsyncEmitter = require('gemini-core').events.AsyncEmitter; const emitter = new AsyncEmitter(); emitter.on('event', function() { return Promise.delay(1000); }); emitter.emitAndWait('event') .then(function() { console.log('All handlers finished'); // Would be called after 1 second }); ``` `emitAndWait` returns promise. #### utils `passthroughEvent(from, to, event)` Passes `event` from `from` to `to`. `event` can be an array of events. ### promiseUtils `waitForResults(promises)` Waits for all promises in array to be resolved or rejected. If any promise is rejected - rejects with the first rejection error, otherwise resolves. ### BrowserAgent Example: ```js const BrowserAgent = require('gemini-core').BrowserAgent; const BrowserPool = require('gemini-core').BrowserPool; const pool = BrowserPool.create(/*BrowserManager, config*/); const browserAgent = BrowserAgent.create('bro-id', pool); return browserAgent.getBrowser(/*{highPriority: true}*/) .then((bro) => { ... return browserAgent.freeBrowser(bro/*, {force: true}*/); }); ``` ### Errors #### CancelledError This error will be thrown on browser pool cancel: ```js const BrowserPool = require('gemini-core').BrowserPool; const CancelledError = require('gemini-core').errors.CancelledError; ... pool.getBrowser('bro') .then((bro) => ...) .catch((e) => { if (e instanceof CancelledError) { console.log('cancelled') } }); pool.cancel(); ``` ### Image API for working with images. ```js const {Image} = require('gemini-core'); const imgBuffer = new Buffer('someBufferString', 'base64'); const image = new Image(imgBuffer); const imageSize = image.getSize(); ``` #### Methods ##### crop Crop image to the passed sizes depending on scale factor. Modifies current image. Returns Promise with image instance. ```js const image = new Image(imgBuffer); const cropArea = { top: 10, left: 10, width: 100, height: 100 }; image.crop(cropArea, 2); // will crop double sized image i.e width=200, heigth=200 etc. ``` ##### getSize Returns object with current image size e.g. `{width: 100, height: 100}` ##### getRGBA Returns RGBA color of the passed image pixel in row. Takes pixel number in row as first argument and row nomber as second. Returns object with color. ```js const image = new Image(imgBuffer); const color = image.getRGBA(1, 2); // {r: 255, g: 0, b: 0, a:255} ``` ##### save Save image to the passed path. Asynchronous operation. Returns Promise with current image instance. ##### clear Fill image area with black color depending on scale factor. ```js const image = new Image(imgBuffer); const clearArea = { top: 10, left: 10, width: 100, height: 100 }; image.clear(clearArea, {scaleFactor: 1}); ``` ##### join Append another image to current. Modifies current image. ```js const image1 = new Image(imgBuffer); const image2 = new Image(imgBuffer); image1.join(image2); ``` #### Static methods ##### fromBase64 Returns new Image instance from base64 hash. ##### RGBToString Convert object-like RGB color to string. ```js const color = Image.RGBToString({r: 255, g: 0, b: 0}); // returns #ff0000 ``` ##### compare Compare images with passed options. Asynchronous operation. Returns compare result sa Boolean value. ```js const opts = { canHaveCaret: true, pixelRatio: 1, tolerance: 2, antialiasingTolerance: 3 }; return Image.compare(path1, path2, opts) .then((isEqual) => { console.log(isEqual); }); ``` ##### buildDiff Save new diff image with passed options on the file system. ```js const diffOpts = { reference: '/ref/path/image.png', current: '/curr/path/image.png', diff: '/diff/path/image.png', diffColor: '#f5f5f5', tolerance: 2 }; return Image.buildDiff(diffOpts); // will save image with diff to /diff/path/image.png ``` ### Temp Class for creating temp direcroty for image save. Directory will be removed on process end. #### init Init temp directory. #### path Generate random path relative temp directory. #### serialize Serialize Temp instance. #### attach Attach passed directory to the current Temp instance. ### clientBdridge ```js const {clientBridge} = require('gemini-core'); return clientBridge.build(browser, {calibration, coverage}); ``` ### coverageLevel ```js const {coverage: {coverageLevel}} = require('gemini-core'); coverageLevel.merge(oldValue, newValue); ```