{"id":41641028,"url":"https://github.com/petecoop/phantasma","last_synced_at":"2026-01-24T15:10:02.477Z","repository":{"id":28238343,"uuid":"31743344","full_name":"petecoop/phantasma","owner":"petecoop","description":"A high level promise based wrapper for phantomjs","archived":false,"fork":false,"pushed_at":"2019-03-07T18:11:57.000Z","size":46,"stargazers_count":33,"open_issues_count":5,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-11-27T09:31:27.792Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/petecoop.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-05T23:56:06.000Z","updated_at":"2025-07-23T21:22:30.000Z","dependencies_parsed_at":"2022-09-04T17:01:10.630Z","dependency_job_id":null,"html_url":"https://github.com/petecoop/phantasma","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/petecoop/phantasma","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petecoop%2Fphantasma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petecoop%2Fphantasma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petecoop%2Fphantasma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petecoop%2Fphantasma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/petecoop","download_url":"https://codeload.github.com/petecoop/phantasma/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/petecoop%2Fphantasma/sbom","scorecard":{"id":728485,"data":{"date":"2025-08-11","repo":{"name":"github.com/petecoop/phantasma","commit":"237278721cd4586eaa30272569817a508cfd3113"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":2,"reason":"Found 4/17 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENCE:0","Info: FSF or OSI recognized license: ISC License: LICENCE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 18 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T13:39:11.765Z","repository_id":28238343,"created_at":"2025-08-22T13:39:11.765Z","updated_at":"2025-08-22T13:39:11.765Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28730315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-01-24T15:10:01.803Z","updated_at":"2026-01-24T15:10:02.450Z","avatar_url":"https://github.com/petecoop.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"**No longer maintained**\n\nI'd really recommend using [Puppeteer](https://github.com/GoogleChrome/puppeteer), which solves the problem I was trying to solve here and is also really nice and quick.\n\n# Phantasma\n[![Build Status](https://img.shields.io/travis/petecoop/phantasma.svg)](https://travis-ci.org/petecoop/phantasma)\n[![NPM Version](https://img.shields.io/npm/v/phantasma.svg)](https://www.npmjs.org/package/phantasma)\n[![NPM Downloads](https://img.shields.io/npm/dm/phantasma.svg)](https://www.npmjs.org/package/phantasma)\n\n\nA high level promise based wrapper for [PhantomJS](http://phantomjs.org/)\n\nThe aim is to make interacting with PhantomJS from node as simple as possible. All actions are asynchronous and return a [bluebird](https://www.npmjs.org/package/bluebird) promise. The promises have been extended with Phantasma methods, allowing for a fluent API.\n\nThis project is heavily influenced by [Nightmare](https://github.com/segmentio/nightmare), but different - Nightmare queues up actions which are then exectued when `.run()` is called, once this is done phantomjs is exited. This is fine if you already know the actions you want to take however it's not possible to change the flow of actions mid-way e.g. if sometimes a popup/button appears on a page that you want to click before continuing with the next action. Phantasma takes a different approach - using promises which leaves queueing up to the promise library (bluebird) and leaves you in control of when to exit the phantomjs process.\n\n## Install\n\n- Install PhantomJs: http://phantomjs.org/download.html\n\n- `npm install phantasma`\n\n## Examples\n\n```js\nvar Phantasma = require('phantasma');\n\nvar ph = new Phantasma();\n\nph.open('https://duckduckgo.com')\n  .type('#search_form_input_homepage', 'phantomjs')\n  .click('#search_button_homepage')\n  .wait()\n  .screenshot('screenshot.png')\n  .evaluate(function () {\n    return document.querySelectorAll('.result').length;\n  })\n  .then(function (num) {\n    console.log(num + ' results');\n  })\n  .catch(function (e) {\n    console.log('error', e);\n  })\n  .finally(function () {\n    console.log('done!');\n    ph.exit();\n  });\n```\n\nAny of the above methods can be replaced with a `.then` e.g.\n\n```js\nvar Phantasma = require('phantasma');\n\nvar ph = new Phantasma();\n\nph.then(function () {\n    return ph.open('https://duckduckgo.com');\n  })\n  .screenshot('screenshot.png')\n  .finally(function () {\n    ph.exit();\n  });\n\n```\n\nThis allows for conditionally changing the flow depending on the result of the last request:\n\n```js\nvar ph = new Phantasma();\n\nph.open('https://duckduckgo.com')\n  .type('#search_form_input_homepage', 'akjsdhjashda')\n  .click('#search_button_homepage')\n  .wait()\n  .evaluate(function () {\n    return document.querySelectorAll('.result').length;\n  })\n  .then(function (num) {\n    if(!num){\n      return ph.type('#search_form_input', 'phantomjs')\n        .click('#search_button')\n        .wait()\n        .screenshot('screenshot.png');\n    }\n    return ph.screenshot('screenshot.png');\n  })\n  .finally(function () {\n    ph.exit();\n  });\n```\n\n\n## API\n\n#### new Phantasma(options)\nCreate a new instance, initiates the phantomjs instance\n\nThe available options are:\n\n- `diskCache: [true|false]`: enables disk cache (default is `false`).\n- `ignoreSslErrors: [true|false]`: ignores SSL errors, such as expired or self-signed certificate errors (default is `true`).\n- `loadImages: [true|false]`: load all inlined images (default is `true`).\n- `localStoragePath: '/some/path'`: path to save LocalStorage content and WebSQL content (no default).\n- `localStorageQuota: [Number]`: maximum size to allow for data (no default).\n- `localToRemoteUrlAccess: [true|false]`: allows local content to access remote URL (default is `false`).\n- `maxDiskCacheSize: [Number]`: limits the size of disk cache in KB (no default).\n- `binary`: specify a different custom path to PhantomJS (no default).\n- `port: [Number]`: specifies the phantomjs port.\n- `proxy: 'address:port'`: specifies the proxy server to use (e.g. `proxy: '192.168.1.42:8080'`) (no default).\n- `proxyType: [http|socks5|none]`: specifies the type of the proxy server (default is `http`) (no default).\n- `proxyAuth`: specifies the authentication information for the proxy, e.g. `proxyAuth: 'username:password'`) (no default).\n- `sslProtocol: [sslv3|sslv2|tlsv1|any]` sets the SSL protocol for secure connections (default is `any`).\n- `sslCertificatesPath: '/some/path'` Sets the location for custom CA certificates (if none set, uses system `default`).\n- `timeout [Number]`: how long to wait for page loads in ms (default is `5000`).\n- `webSecurity: [true|false]`: enables web security and forbids cross-domain XHR (default is `true`).\n\n#### Page Settings\nThese options can be passed into `new Phantasma(options)`, alternatively they can be set individually afterwards using the `.pageSetting(setting, value)` method.\n\n- `javascriptEnabled: [true|false]`: defines whether to execute the script in the page or not (defaults to `true`).\n- `loadImages: [true|false]`: defines whether to load the inlined images or not (defaults to `true`).\n- `localToRemoteUrlAccessEnabled: [true|false]`: defines whether local resource (e.g. from file) can access remote URLs or not (defaults to `false`).\n- `userAgent: String`: defines the user agent sent to server when the web page requests resources.\n- `userName: String`: sets the user name used for HTTP authentication.\n- `password: String`: sets the password used for HTTP authentication.\n- `XSSAuditingEnabled: [true|false]`: defines whether load requests should be monitored for cross-site scripting attempts (defaults to `false`).\n- `webSecurityEnabled: [true|false]`: defines whether web security should be enabled or not (defaults to `true`).\n- `resourceTimeout: Number`: (in milli-secs) defines the timeout after which any resource requested will stop trying and proceed with other parts of the page. `onResourceTimeout` event will be called on timeout.\n\n### Methods\n\n#### .open(url)\nLoad the page at `url`. Will throw a Timeout error if it takes longer to complete than the timeout setting.\n\n#### .wait()\nWait until a page finishes loading, typically after a `.click()`. Will throw a Timeout error if it takes longer to complete than the timeout setting.\n\n#### .exit()\nClose the phantomjs process.\n\n#### .click(selector)\nClicks the `selector` element.\n\n#### .click(x, y)\nClicks at the position given.\n\n#### .type(selector, text)\nEnters the `text` provided into the `selector` element.\n\n#### .value(selector, text)\nSets the `text` provided as the value of the `selector` element.\n\n#### .select(selector, value)\nSets the `value` of a select element to `value`.\n\n#### .evaluate(fn, arg1, arg2,...)\nInvokes `fn` on the page with `arg1, arg2,...`. All the `args` are optional. On completion it passes the return value of `fn` to the resolved promise. Example:\n\n```js\nvar Phantasma = require('phantasma');\nvar p1 = 1;\nvar p2 = 2;\n\nvar ph = new Phantasma();\n\nph.evaluate(function (param1, param2) {\n    // now we're executing inside the browser scope.\n    return param1 + param2;\n  }, p1, p2)\n  .then(function (result) {\n    // now we're inside Node scope again\n    console.log(result);\n  })\n  .finally(function () {\n    ph.exit();\n  });\n```\n\n#### .viewport(width, height)\nSet the viewport dimensions\n\n#### .screenshot(path)\nSaves a screenshot of the current page to the specified `path`. Useful for debugging. Note the path must include the file extension. Supported formats include .png, .gif, .jpeg, and .pdf.\n\n#### .screenshotDomElement(selector,path)\nSaves an screenshot of an specific DOM element as image to the specified `path`.Note the path must include the file extension. Supported formats include .png, .gif, .jpeg, and .pdf.\n\n#### .title()\nGet the title of the current page, the result is passed to the resolved promise.\n\n#### .url()\nGet the url of the current page, the result is passed to the resolved promise.\n\n#### .back()\nGo back to the previous page. This will `.wait()` untill the page has loaded.\n\n#### .forward()\nGo forward to the next page. This will `.wait()` untill the page has loaded.\n\n#### .refresh()\nrefresh the current page. This will `.wait()` untill the page has loaded.\n\n#### .focus(selector)\nFocus the `selector` element.\n\n#### .injectJs(path)\nInject javascript at `path` into the currently open page.\n\n#### .injectCss(style)\nInject CSS string `style` into the currently open page.\n\n#### .content(html)\nGet or set the content of the page, if `html` is set it will set, if not it will get.\n\n#### .pageSetting(setting, value)\nSet a page setting.\n\n### Events\n\nEvents extends node's EventEmitter.\n\n#### .on(event, callback)\nExecutes `callback` when the `event` is emitted.\n\nExample:\n\n```js\nvar Phantasma = require('phantasma');\n\nvar ph = new Phantasma();\n\nph.open('https://duckduckgo.com')\n  .type('#search_form_input_homepage', 'phantomjs')\n  .click('#search_button_homepage')\n  .wait()\n  .catch(function (e) {\n    console.log('error', e);\n  })\n  .finally(function () {\n    console.log('done!');\n    ph.exit();\n  }).on('onUrlChanged', function (url) {\n    console.log('url change', url);\n  });\n```\n\n#### .once(event, callback)\nExecutes `callback` when the `event` is emitted only once.\n\n#### .removeListener(event, callback)\nRemoves `callback` from `event` listener.\n\n#### Supported Events:\n\nSupports the following phantomjs events, you can read more on these here ([PhantomJS callbacks](https://github.com/ariya/phantomjs/wiki/API-Reference-WebPage#callbacks-list)):\n\n- `onAlert` - callback(msg)\n- `onConsoleMessage` - callback(msg, lineNum, sourceId)\n- `onError` - callback(msg, trace)\n- `onLoadFinished` - callback(status)\n- `onLoadStarted` - callback()\n- `onNavigationRequested` - callback(url, type, willNavigate, main)\n- `onResourceReceived` - callback(response)\n- `onResourceRequested` - callback(requestData, networkRequest)\n- `onResourceTimeout` - callback(request)\n- `onUrlChanged` - callback(url)\n\n## Promise methods\n\nYou can use any of the methods available to bluebird [found here](https://github.com/petkaantonov/bluebird/blob/master/API.md).\n\nThe most useful methods are:\n\n#### .then(fulfillHandler, rejectHandler)\nReturns a new promise chained from the previous promise. The return value of the previous promise will be passed into this promise.\n\n\n#### .finally(Function handler)\nPass a handler that will be ran regardless of the outcome of the previous promises. Useful for cleaning up the Phantasma process e.g.\n\n```js\n.finally(function () {\n  ph.exit();\n});\n```\n\n#### .catch(Function handler)\nThis is a catch-all exception handler - it can be used to find and log an error. e.g.\n\n```js\n.catch(function (e) {\n  console.log(e);\n});\n```\n\n#### .delay(ms)\nDelay the next promise for `ms` milliseconds\n\n## License \n\n[ISC](http://en.wikipedia.org/wiki/ISC_license)\n\nCopyright (c) 2014, Pete Cooper - pete@petecoop.co.uk\n\nPermission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetecoop%2Fphantasma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpetecoop%2Fphantasma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetecoop%2Fphantasma/lists"}