{"id":13583715,"url":"https://github.com/OnetapInc/chromy","last_synced_at":"2025-04-06T21:32:48.290Z","repository":{"id":20719294,"uuid":"90714988","full_name":"OnetapInc/chromy","owner":"OnetapInc","description":"Chromy is a library for operating headless chrome. 🍺🍺🍺","archived":false,"fork":false,"pushed_at":"2022-12-06T16:31:44.000Z","size":382,"stargazers_count":603,"open_issues_count":41,"forks_count":41,"subscribers_count":30,"default_branch":"master","last_synced_at":"2024-04-14T21:52:56.750Z","etag":null,"topics":["browser","casperjs","chrome","headless-chrome","javascript","nightmare","node"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OnetapInc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-09T07:19:56.000Z","updated_at":"2024-02-13T15:41:01.000Z","dependencies_parsed_at":"2023-01-13T21:06:56.746Z","dependency_job_id":null,"html_url":"https://github.com/OnetapInc/chromy","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OnetapInc%2Fchromy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OnetapInc%2Fchromy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OnetapInc%2Fchromy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OnetapInc%2Fchromy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OnetapInc","download_url":"https://codeload.github.com/OnetapInc/chromy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246450412,"owners_count":20779407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","casperjs","chrome","headless-chrome","javascript","nightmare","node"],"created_at":"2024-08-01T15:03:43.288Z","updated_at":"2025-04-06T21:32:47.967Z","avatar_url":"https://github.com/OnetapInc.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Chromy\n\nChromy is a library for operating headless chrome.\n\nDocument Site: https://onetapinc.github.io/chromy/\n\nChromy is similar to Nightmare.js but has some differences:\n\n - Controlling Chrome via Chrome DevTools Protocol.\n - Supports mobile emulation.\n - No need to prepare a screen such as xvfb.\n\n## Requirements\n\n - Node 6 or later\n - Install Chrome60 or later to your machine before use Chromy.\n\nheadless mode is supported by Chrome59 or later.\n\n## Installation\n\n```bash\nnpm i chromy\n```\n\n## Usage\n\n```js\nconst Chromy = require('chromy')\n\n// not headless\n// let chromy = new Chromy({visible:true})\nlet chromy = new Chromy()\nchromy.chain()\n      .goto('http://example.com/')\n      .evaluate(() =\u003e {\n        return document.querySelectorAll('*').length\n      })\n      .result((r) =\u003e console.log(r))\n      .end()\n      .then(() =\u003e chromy.close())\n```\n\nYou can also use async/await interfaces like this:\n\n```js\nconst Chromy = require('chromy')\n\nasync function main () {\n  let chromy = new Chromy()\n  await chromy.goto('http://example.com/')\n  const result = await chromy.evaluate(() =\u003e {\n          return document.querySelectorAll('*').length\n        })\n  console.log(result)\n  await chromy.close()\n}\n\nmain()\n```\n\n### Mobile Emulation\n\nChromy provides mobile emulation.  \nThe emulation changes a screen resolution, density, userAgent and provides touch emulation.\n\n```js\nconst Chromy = require('chromy')\n\nlet chromy = new Chromy()\nchromy.chain()\n      .emulate('iPhone6')\n      .goto('http://example.com/')\n      .tap(100, 100) // emulate tap action by synthesizing touch events.\n      .evaluate(() =\u003e {\n        return navigator.userAgent\n      })\n      .result(console.log)\n      .end()\n      .then(() =\u003e chromy.close())\n```\n\n## FAQ\n\n[FAQ](https://github.com/OnetapInc/chromy/wiki/FAQ)\n\n## API\n\n * [Chromy(options)](#chromyoptions)\n    * [.start(startingUrl = null)](#startstartingurl--null)\n    * [.goto(url, options = {})](#gotourl-options--)\n    * [.waitLoadEvent()](#waitloadevent)\n    * [.userAgent(ua)](#useragentua)\n    * [Chromy.addCustomDevice(device)](#chromyaddcustomdevicedevice)\n    * [.emulate(deviceName)](#emulatedevicename)\n    * [.forward()](#forward)\n    * [.back()](#back)\n    * [.inject(type, file)](#injecttype-file)\n    * [.evaluate(func|source)](#evaluatefuncsourceargs)\n    * [.result(func)](#resultfunc)\n    * [.end()](#end)\n    * [.exists(selector)](#existsselector)\n    * [.visible(selector)](#visibleselector)\n    * [.wait(msec)](#waitmsec)\n    * [.wait(selector)](#waitselector)\n    * [.wait(func)](#waitfunc)\n    * [.sleep(msec)](#sleepmsec)\n    * [.type(selector, text)](#typeselector-text)\n    * [.insert(selector, text)](#insertselector-text)\n    * [.check(selector)](#checkselector)\n    * [.uncheck(selector)](#uncheckselector)\n    * [.select(selector, value)](#selectselector-value)\n    * [.setFile(selector, files)](#setfileselector-files)\n    * [.click(selector, options)](#clickselector-options)\n    * [.mouseMoved(x, y, options = {})](#mousemovedx-y-options--)\n    * [.mousePressed(x, y, options = {})](#mousepressedx-y-options--)\n    * [.mouseReleased(x, y, options = {})](#mousereleasedx-y-options--)\n    * [.tap(x, y, options = {})](#tapx-y-options--)\n    * [.doubleTap(x, y, options = {})](#doubletapx-y-options--)\n    * [.scroll(x, y)](#scrollx-y)\n    * [.scrollTo(x, y)](#scrolltox-y)\n    * [.rect(selector)](#rectselector)\n    * [.rectAll(selector)](#rectallselector)\n    * [.defineFunction(func)](#definefunctionfunc)\n    * [.on(eventName, listener)](#oneventname-listener)\n    * [.once(eventName, listener)](#onceeventname-listener)\n    * [.removeListener(eventName, listener)](#removelistenereventname-listener)\n    * [.removeAllListeners(eventName)](#removealllistenerseventname)\n    * [.screenshot(options= {})](#screenshotoptions-)\n    * [.screenshotSelector(selector, options={})](#screenshotselectorselector-options)\n    * [.screenshotMultipleSelectors(selectors, callback, options = {})](#screenshotmultipleselectorsselectors-callback-options--)\n    * [.screenshotDocument(options = {})](#screenshotdocumentoptions--)\n    * [.pdf(options={})](#pdfoptions)\n    * [.startScreencast(callback, options = {})](#startscreencastcallback-options--)\n    * [.stopScreencast()](#stopscreencast)\n    * [.console(func)](#consolefunc)\n    * [.receiveMessage(func)](#receivemessagefunc)\n    * [.ignoreCertificateErrors()](#ignorecertificateerrors)\n    * [.blockUrls(urls)](#blockurlsurls)\n    * [.clearBrowserCache()](#clearbrowsercache)\n    * [.setCookie(params)](#setcookieparams)\n    * [.getCookies(params)](#getcookieparams)\n    * [.deleteCookie(name, url = null)](#deletecookiename-url--null)\n    * [.clearAllCookies()](#clearallcookies)\n    * [.clearDataForOrigin (origin = null, type = 'all')](#cleardatafororigin-origin--null-type--all)\n    * [.getDOMCounters()](#getdomcounters)\n    * [.static cleanup()](#static-cleanup)\n\n##### Chromy(options)\n\n###### options  \n\n - host(default: localhost): host address\n - port(default: 9222): --remote-debugging-port  \n - userDataDir(default: null): Chrome profile path. This option can be used to persist an user profile.\n - launchBrowser(default: true): If you want chromy to attach to the Chrome instance that is already launched, set to false.\n - visible(default: false): If set to true, chrome is launched in visible mode. This option is not used if launchBrowser is false.\n - chromePath(default: null): This option is used to find out an executable of Chrome. If set to null, executable is selected automatically. This option is not used if launchBrowser is false.\n - enableExtensions(default: false): Enable extension loading. (Generally, this options is used with userDataDir option)\n - chromeFlags(default: []): These flags is passed to Chrome. Each flag must have a prefix string \"--\". This option is not used if launchBrowser is false.\n - waitTimeout(default: 30000): If wait() doesn't finish in the specified time WaitTimeoutError will be thrown.\n - gotoTimeout(default: 30000): If goto() doesn't finish in the specified time GotoTimeoutError will be thrown.\n - evaluateTimeout(default: 30000): If evaluate() doesn't finish in the specified time EvaluateTimeError will be thrown.\n - waitFunctionPollingInterval(default: 100): polling interval for wait().\n - typeInterval(default: 20): This option is used only in type() method.\n - activateOnStartUp(default: true): activate a first tab on startup. this option is enable only in visible mode.\n\n\n##### .start(startingUrl = null)\n\nLaunches Chrome browser.\n\n###### options\n\nstartingUrl: a staring url. If you set to null 'about:blank' is used as a starting url.\n\n##### .goto(url, options = {})\n\nGoes to url. If you have not called start(), this method calls start(url) automatically.\n\n###### options\n\nwaitLoadEvent(default: true): If set to false, goto() doesn't wait until load event is fired.\n\n###### returns\n\nReturns [Response object](https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-Response)\n\n##### .waitLoadEvent()\n\nwait until a load event is fired.\n\n##### .userAgent(ua)\n\nset a useragent.\n\nua: new user agent.\n\n##### Chromy.addCustomDevice(device)\n\nadd custom device definitions to emulate it.\n\nSee [src](src/devices.js).\n\n##### .emulate(deviceName)\n\nemulate a device that is defined by `Chromy.addCustomDevice()`.\n\n##### .forward()\n\ngo forward to the next page and wait until load event is fired.\n\n##### .back()\n\ngo back to the previous page and wait until load event is fired.\n\n##### .inject(type, file)\n\nInjects a file into browser as a javascript or a css.\n\ntype: must be 'js' or 'css'\nfile: injected file.\n\n##### .evaluate(func|source, args)\n\nEvaluates a expression in the browser context.  \nIf the expression returns a Promise object, the promise is resolved automatically.\n\n##### .result(func)\n\nresult() receives a result of previous directive.\n\n```js\nchromy.chain()\n      .goto('http://example.com')\n      .evaluate(() =\u003e {\n        return document.querySelectorAll('*').length\n      })\n      .result((length) =\u003e {\n        // length is a result of evaluate() directive.\n        console.log(length)\n      }\n      .end()\n```\n\n##### .end()\n\n##### .exists(selector)\n\nReturns whether an node matched with the selector is exists.\n\n##### .visible(selector)\n\nReturns whether an node matched with the selector is exists and visible.\n\n##### .wait(msec)\n\nalias for .sleep(msec)\n\n##### .wait(selector)\n\nwait until selector you specified appear in a DOM tree.\n\n##### .wait(func)\n\nwait until function you supplied is evaluated as true. func() executes in browser window context.\n\n##### .sleep(msec)\n\nwait for milli seconds you specified.\n\n##### .type(selector, text)\n\n##### .insert(selector, text)\n\n##### .check(selector)\n\n##### .uncheck(selector)\n\n##### .select(selector, value)\n\n##### .setFile(selector, files)\n\nSets the files to a file field that matches the selector.\n\n - selector: selector for specifying the file field.\n - files: The array or string value that represents a local file path.\n\n##### .click(selector, options)\n\n###### options\n\nwaitLoadEvent(default: false): If set to true, wait until load event is fired after click event is fired.\n\n##### .mouseMoved(x, y, options = {})\n\nDispatch mousemoved event.\n\n##### .mousePressed(x, y, options = {})\n\nDispatch mousedown event.\n\n##### .mouseReleased(x, y, options = {})\n\nDispatch mouseup event.\n\n##### .tap(x, y, options = {})\n\nSynthesize tap by dispatching touch events.\n(NOTE: To dispatch touch events you need to enable a mobile emulation before.)\n\n##### .doubleTap(x, y, options = {})\n\nSynthesize double tap by dispatching touch events.\n(NOTE: To dispatch touch events you need to enable a mobile emulation before.)\n\n##### .scroll(x, y)\n\nScrolls to the position. x and y means relative position.\n\n##### .scrollTo(x, y)\n\nScrolls to the position. x and y means absolute position.\n\n##### .rect(selector)\n\nReturns a rect of the element specified by selector.\n\n##### .rectAll(selector)\n\nReturns an array of rects that is specified by selector.\n\n##### .defineFunction(func)\n\n```js\nfunction outerFunc () {\n  return 'VALUE'\n}\nchromy.chain()\n      .goto('http://example.com')\n      .defineFunction(outerFunc)\n      .evaluate(() =\u003e {\n        outerFunc()\n      })\n      .end()\n```\n\n##### .send(eventName, parameter)\n\nCalls DevTools protocol directly.\n\n##### .on(eventName, listener)\n\nAdds the listener function.\n\n##### .once(eventName, listener)\n\nAdds one time listener function.\n\n##### .removeListener(eventName, listener)\n\nRemoves the listener function.\n\n##### .removeAllListeners(eventName)\n\nRemoves all listener function.\n\n##### .screenshot(options= {})\n\nExports a current screen as an image data.\n\nSee examples: [examples/screenshot.js](examples/screenshot.js)\n\n###### options\n\n - format(default: 'png'): must be either 'png' or 'jpeg'\n - quality(default: 100): quality of image.\n - fromSurface(default: true): if set to true, take screenshot from surface.\n - useDeviceResolution(default: false): if set to true, the image will have same resolution with device.\n\n##### .screenshotSelector(selector, options={})\n\nExports an area of selector you specified as an image data.\n\nSee examples: [examples/screenshot.js](examples/screenshot.js)\n\nNote:\n\n - The size of target specified by selector must be smaller than viewport size. If not, image gets cropped.\n - It has a side-effect. After this api is called, scroll position is moved to target position.\n\n###### options\n\nSee screenshot()\n\n##### .screenshotMultipleSelectors(selectors, callback, options = {})\n\nTakes multiple screenshot specified by selector at once.\nEach image can be received by callback.\n\nLimitation:\n - It is impossible that taking a screenshot of the element positioned at below of 16384px because of limitation of chrome.\n   Detail: https://groups.google.com/a/chromium.org/d/msg/headless-dev/DqaAEXyzvR0/P9zmTLMvDQAJ\n\n###### Parameter\n\n - selectors: An array of selector\n - callback: function(error, image, index, selectors, subIndex)\n   - error: error information.\n   - image: image data\n   - index: index of selectors.\n   - subIndex: this value is used only if useQuerySelecotrAll is true.\n - options:  \n   - model: see explanation of screenDocument()\n   - format: see explanation of screenshot()\n   - quality: see explanation of screenshot()\n   - fromSurface: see explanation of screenshot()\n   - useQuerySelectorAll(default: false): If set to true, take all the screenshot of elements returned from document.querySelectorAll() (Since v 0.2.13)\n\n##### .screenshotDocument(options = {})\n\nExports a entire document as an image data.\n\nSee examples: [examples/screenshot.js](examples/screenshot.js)\n\nLimitation:\n  - Cannot take a screenshot of an area under 16384px.\n    Detail: https://groups.google.com/a/chromium.org/d/msg/headless-dev/DqaAEXyzvR0/P9zmTLMvDQAJ\n\nKnown Issue:\n\n - When this api is called to take large page sometimes strange white area is appeared. This result is caused by --disable-flag option passed to Chrome. After chrome 60 is officially released I remove --disable-flag option to fix this problem.\n\n###### options\n\n - model: this parameter affect page size. must be which one of: 'box', 'scroll'. 'box' means box model of body element. 'scroll' means size of scroll area.\n - format: see explanation of screenshot()\n - quality: see explanation of screenshot()\n - fromSurface: see explanation of screenshot()\n\n##### .pdf(options={})\n\nExports a current page's printing image as a PDF data.\nThis function is supported only in headless mode (since Chrome60).\n\nSee examples: [examples/screenshot.js](examples/screenshot.js)\n\n###### Parameters\n\n - options: See [devtools protocol](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF)\n\n##### .startScreencast(callback, options = {})\n\nStarts screencast to take screenshots by every frame.\n\nSee examples: [examples/screencast.js](examples/screenshot.js)\n\n###### Parameter\n\ncallback: callback function for receiving parameters of screencastFrame event. See details [here](https://chromedevtools.github.io/devtools-protocol/tot/Page/#event-screencastFrame)\noptions: See details [here](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-startScreencast).\n\n##### .stopScreencast()\n\nStops screencast.\n\n##### .console(func)\n\n```js\nchromy.chain()\n      .goto('http://example.com')\n      .console((text) =\u003e {\n        console.log(text)\n      })\n      .evaluate(() =\u003e {\n        console.log('HEY')\n      })\n      .end()\n```\n\n##### .receiveMessage(func)\n\nreceive a message from browser.  \n\nYou can communicate with a browser by using receiveMessage() and sendToChromy().\nsendToChromy() is a special function to communicate with Chromy.\nWhen you call receiveMessage() at the first time, sendToChromy() is defined in a browser automatically.\nA listener function passed to receiveMessage() receives parameters when sendToChromy() is executed in a browser.\n\n\n```js\nchromy.chain()\n      .goto('http://example.com')\n      .receiveMessage((msg) =\u003e {\n        console.log(msg[0].value)\n      })\n      .evaluate(() =\u003e {\n        sendToChromy({value: 'foo'})\n      })\n```\n\n##### .ignoreCertificateErrors()\n\nIgnores all certificate errors.\n\n```js\nchromy.chain()\n      .ignoreCertificateErrors()\n      .goto('https://xxxxx/')\n      .end()\n```\n\n##### .blockUrls(urls)\n\nblocks urls from loading.  \n\n###### Parameter\n\nurls: array[string]  \nWildcard('*') is allowed in url string.\n\n##### .clearBrowserCache()\n\nRemoves all browser caches.\n\n##### .setCookie(params)\n\n###### Parameters\n\nparams: object or array\n\nSee [chrome document](https://chromedevtools.github.io/devtools-protocol/tot/Network/#method-setCookie)\nIf url parameter is not set, current url(location.href) is used as default value.\n\n##### .getCookies(name = null)\n\n###### Parameters\n\nname: string or array of string\n\nSee [chrome document](https://chromedevtools.github.io/devtools-protocol/tot/Network/#method-getCookies)\n\n##### .deleteCookie(name, url = null)\n\nRemove a cookie.\n\n###### Parameters\n\nname: string or array of string\nurl: url associated with cookie. If url is not set, current url(location.href) is used as default value.\n\n##### .clearAllCookies()\n\nRemoves all browser cookies.\n\n##### .clearDataForOrigin (origin = null, type = 'all')\n\nClear data for origin.(cookies, local_storage, indexedDb, etc...)\n\nSee details [here](https://chromedevtools.github.io/devtools-protocol/tot/Storage/#method-clearDataForOrigin).\n\n##### .getDOMCounters()\n\nGet count of these item: document, node, jsEventListeners\n\nSee details [here](https://chromedevtools.github.io/devtools-protocol/tot/Memory/#method-getDOMCounters).\n\n##### .static cleanup()\n\nclose all browsers.\n\n```js\nprocess.on('SIGINT', async () =\u003e {\n  await Chromy.cleanup()\n  process.exit(1)\n})\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/OnetapInc/chromy\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOnetapInc%2Fchromy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOnetapInc%2Fchromy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOnetapInc%2Fchromy/lists"}