{"id":24762240,"url":"https://github.com/uxter/guit","last_synced_at":"2025-10-11T09:31:38.285Z","repository":{"id":57256704,"uuid":"77120104","full_name":"uxter/guit","owner":"uxter","description":":beetle: The JavaScript framework for testing.","archived":false,"fork":false,"pushed_at":"2019-03-28T08:44:49.000Z","size":207,"stargazers_count":10,"open_issues_count":0,"forks_count":24,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-23T23:58:49.773Z","etag":null,"topics":["async-await","junit-report","reporter","screenshot-testing","spec","suite","test-automation","testing","ui-testing","web-apps","web-ui"],"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/uxter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-12-22T06:50:01.000Z","updated_at":"2025-09-05T01:06:05.000Z","dependencies_parsed_at":"2022-08-25T02:30:57.938Z","dependency_job_id":null,"html_url":"https://github.com/uxter/guit","commit_stats":null,"previous_names":["shcoder-ru/guit"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/uxter/guit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uxter%2Fguit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uxter%2Fguit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uxter%2Fguit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uxter%2Fguit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uxter","download_url":"https://codeload.github.com/uxter/guit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uxter%2Fguit/sbom","scorecard":{"id":913782,"data":{"date":"2025-08-11","repo":{"name":"github.com/uxter/guit","commit":"d7d7b53373c4b0bd81a131615673875ca191e042"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"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":"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":"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":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","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":"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":"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":"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":"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":"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: LICENSE.txt:0","Info: FSF or OSI recognized license: ISC License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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":"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 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-24T20:13:41.539Z","repository_id":57256704,"created_at":"2025-08-24T20:13:41.539Z","updated_at":"2025-08-24T20:13:41.539Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006752,"owners_count":26084180,"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","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["async-await","junit-report","reporter","screenshot-testing","spec","suite","test-automation","testing","ui-testing","web-apps","web-ui"],"created_at":"2025-01-28T19:29:09.993Z","updated_at":"2025-10-11T09:31:37.966Z","avatar_url":"https://github.com/uxter.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# :hammer: The development of [the new major version 2](https://github.com/uxter/guit/tree/v2) is being conducted at the moment. [![Build Status](https://travis-ci.org/uxter/guit.svg?branch=v2)](https://travis-ci.org/uxter/guit) [![Coverage Status](https://codecov.io/gh/uxter/guit/branch/v2/graph/badge.svg)](https://codecov.io/gh/uxter/guit) [![Dependency Status](https://david-dm.org/uxter/guit.svg)](https://david-dm.org/uxter/guit) [![Join the chat at https://gitter.im/es-guit](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/es-guit?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n-----\n\n[![GUIT](https://rawgithub.com/uxter/guit/master/images/guit-logo.png)](https://github.com/uxter/guit)\n\nThe JavaScript framework for testing web UI\n\n[![npm package](https://nodei.co/npm/guit.png?downloads=true\u0026downloadRank=true\u0026stars=true)](https://www.npmjs.com/package/guit)\n\n## Installation\n```sh\n# Local installation:\nnpm install --save-dev guit\n\n# Global installation:\nnpm install -g guit\n```\n\n## Usage\n\nTo run your tests in command line\n\n```sh\nguit --help\n#\n#  Usage: guit [options]\n#\n#  Options:\n#\n#    -h, --help               output usage information\n#    --spec-dir \u003cdir\u003e         Specify spec's dir to find\n#    --spec-files \u003cregex\u003e     Specify spec's file regex to run\n#    --helper-dir \u003cdir\u003e       Specify helper's dir to find\n#    --helper-files \u003cregex\u003e   Specify helper's file regex to import\n#    --junit-filename \u003cfile\u003e  Specify junit results file to save\n#\n```\n\nRun the tests using\n\n`guit --spec-dir ./example/spec/ --spec-files \\\\-spec\\\\.js$`\n\nTo run your tests using npm, you may specify scripts in `package.json`\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"guit --spec-dir ./example/spec/ --spec-files \\\\-spec\\\\.js$\"\n  }\n}\n```\n\nRun the tests using `npm test`\n\n## Configuration\n\nYou may specify the config in `.guitrc`\n\n```json\n{\n    \"helperDir\": \"helper\",\n    \"helperFiles\": \".*-helper.js\",\n    \"specDir\": \"spec\",\n    \"specFiles\": [\n        \".*-spec.js\",\n        \".*-spec.json\"\n    ],\n    \"junitFilename\": \"junitresults.xml\"\n}\n```\n\nAlternatively, you may specify the field `guit` in your `package.json`\n\n```json\n{\n  \"guit\": {\n    \"helperDir\": \"helper\",\n    \"helperFiles\": \".*-helper.js\",\n    \"specDir\": \"spec\",\n    \"specFiles\": [\n      \".*-spec.js\",\n      \".*-spec.json\"\n    ],\n    \"junitFilename\": \"junitresults.xml\"\n  }\n}\n```\n\nAnd specify scripts in `package.json`\n\n```json\n{\n  \"scripts\": {\n    \"test\": \"guit\"\n  }\n}\n```\n\n## Global methods\n\n`describe(\"\u003cSUITE DESCRIPTION\u003e\", \u003cFUNCTION\u003e);`    \n`it(\"\u003cCASE DESCRIPTION\u003e\", \u003cFUNCTION\u003e);` (support async await)    \n`beforeAll(\u003cFUNCTION\u003e);` (support async await)    \n`beforeEach(\u003cFUNCTION\u003e);` (support async await)    \n`afterEach(\u003cFUNCTION\u003e);` (support async await)    \n`afterAll(\u003cFUNCTION\u003e);` (support async await)    \n`expect(\u003cACTUAL\u003e)`\n\nguit uses [expect](https://github.com/mjackson/expect)\n\nUsage methods for create specs\n\n```js\ndescribe('Suite 1:', function() {\n\n    beforeAll(function() {\n        this.config = {};\n    });\n\n    beforeEach(function() {\n        this.data = {};\n    });\n\n    it('Spec 1', function() {\n        expect({}).toEqual({});\n    });\n\n    afterEach(function() {\n        delete this.data;\n    });\n\n    afterAll(function() {\n        delete this.config;\n    });\n\n});\n```\n\nUsage with async await\n\n```js\nimport { runServer, stopServer } from 'path/to/server';\nimport { sendRequest } from 'path/to/client'\n\ndescribe('Suite 1:', function() {\n\n    beforeAll(async function() {\n        await runServer();\n    });\n\n    it('Spec 1', async function() {\n        let response1 = await sendRequest({a: 1});\n        let response2 = await sendRequest({a: 2});\n        expect(response1).toNotEqual(response2);\n    });\n\n    afterAll(async function() {\n        await stopServer();\n    });\n\n});\n```\n\nUsage json file for create specs\n```json\n{\n  \"title\": \"Suite 1:\",\n  \"beforeAll\": \"beforeAllForSuite1\",\n  \"afterAll\": \"afterAllForSuite1\",\n  \"beforeEach\": \"beforeEachForSuite1\",\n  \"afterEach\": \"afterEachForSuite1\",\n  \"specs\": [\n    {\n      \"title\": \"Open page:\",\n      \"it\": [\n        {\n          \"action\": \"open\",\n          \"args\": [ \"http://127.0.0.1:3000/\" ]\n        },\n        {\n          \"action\": \"sleep\",\n          \"args\": [ 1000 ]\n        },\n        {\n          \"action\": \"checkView\",\n          \"args\": [ \"main-page\" ]\n        }\n      ]\n    },\n    {\n      \"title\": \"Click button:\",\n      \"it\": [\n        {\n          \"action\": \"mouseEvent\",\n          \"args\": [ \"click\", 110, 300 ]\n        },\n        {\n          \"action\": \"sleep\",\n          \"args\": [ 1000 ]\n        },\n        {\n          \"action\": \"checkView\",\n          \"args\": [ \"main-page-001\" ]\n        }\n      ]\n    }\n  ]\n}\n```\n\n### Helpers\n\nHelper file example\n```js\nexport async function open(url) {\n    await this.browser.open(url);\n}\n\nexport async function sleep(time) {\n    await this.browser.sleep(time);\n}\n\nexport async function mouseEvent(type, x, y) {\n    await this.browser.mouseEvent(type, x, y);\n}\n\nexport async function keyboardEvent(type, key) {\n    await this.browser.keyboardEvent(type, key);\n}\n\nexport async function beforeAllForSuite1 {\n    // start this.browser\n    // start this.server\n}\n\nexport async function afterAllForSuite1 {\n    // stop this.browser\n    // stop this.server\n}\n\nexport async function beforeEachForSuite1 {\n    // ...\n}\n\nexport async function afterEachForSuite1 {\n    // ...\n}\n```\n\n## Tools\n\n### Browser\n\n```js\nimport { Browser } from 'guit';\n```\n\nInitializing\n\n```js\nlet browserInstance = await new Browser({\n    width: \u003cWIDTH px\u003e,\n    height: \u003cWIDTH px\u003e,\n    checkTimeout: \u003cTIME ms\u003e,\n    doneTimeout: \u003cTIME ms\u003e\n});\n```\n\nMethods\n\nOpen page in browser\n```js\nawait browserInstance.open(\u003cURL\u003e);\n```\n\nClose page\n```js\nawait browserInstance.close();\n```\n\nClose browser\n```js\nawait browserInstance.exit();\n```\n\nRender view into image\n```js\nawait browserInstance.render(\u003cIMAGE PATH\u003e);\n```\n\nSleep\n```js\nawait browserInstance.sleep(\u003cTIME ms\u003e);\n```\n\nFire mouse event\n```js\nawait browserInstance.mouseEvent(\n    \u003cTYPE\u003e,\n    \u003cPOSITION X\u003e,\n    \u003cPOSITION X\u003e,\n    \u003cBUTTON left|right\u003e\n);\n```\n\nFire keyboard event\n```js\nawait browserInstance.keyboardEvent(\u003cTYPE\u003e, \u003cKEY\u003e);\n```\n\nReturn snapshot of computed style\n```js\nawait browserInstance.getSnapshot(\u003cIGNORE ATTRIBUTES (array)\u003e);\n```\n\nSave snapshot of computed style\n```js\nawait browserInstance.saveSnapshot(\u003cPATH TO FILE\u003e, \u003cSNAPSHOT\u003e);\n```\n\nLoad snapshot of computed style\n```js\nawait browserInstance.loadSnapshot(\u003cPATH TO FILE\u003e);\n```\n\nCompare current snapshot with saved snapshot\n```js\nawait browserInstance.diffSnapshot(\n    \u003cACTUAL SNAPSHOT\u003e,\n    \u003cORIGINAL SNAPSHOT\u003e,\n    \u003cDEVIATION ATTRIBUTES (object)\u003e\n);\n```\n\nCompare current snapshot with saved snapshot\n```js\nawait browserInstance.diffView(\n    \u003cPATH TO ACTUAL IMAGE\u003e,\n    \u003cPATH TO EXPECTED IMAGE\u003e,\n    \u003cPATH TO DIFF IMAGE\u003e\n);\n```\n\nUsage Browser\n\n```js\nimport { runServer } from '../server';\nimport { Browser } from 'guit';\n\ndescribe('Page specs:', function() {\n\n    beforeEach(async function() {\n        this.closeServer = await runServer(3179);\n        this.browser = await new Browser({\n            width: 1280,\n            height: 1024,\n            checkTimeout: 100,\n            doneTimeout: 5000,\n            args: [\n                '--proxy=http://127.0.0.1:8080' // http proxy server\n            ]\n        });\n    });\n\n    it('page spec', async function() {\n        await this.browser.open('http://localhost:3179/');\n        // await this.browser.render('example/spec/test3-page.png');\n        let diff = await this.browser.diffView(\n            'tmp/test3-page.png',\n            'example/spec/test3-page.png',\n            'tmp/test3-page-diff.png',\n        );\n        expect(diff.percentage).toBe(0);\n    });\n\n    afterEach(function() {\n        this.browser.close();\n        this.closeServer();\n    });\n\n});\n```\n\n[Supported args](https://github.com/ariya/phantomjs/blob/master/src/config.cpp#L47)\n\n### Add custom reporter\n\n```js\nimport { addReporter } from 'guit';\n```\n\nUsage `addReporter(CustomReporterClass)`\n\n```js\nexport default class CustomReporterClass {\n\n    constructor(config) { /* ... */}\n\n    started() { /* ... */}\n\n    suiteStarted(suite) { /* ... */}\n\n    specStarted(spec) { /* ... */}\n\n    specDone(spec) { /* ... */}\n\n    suiteDone(suite) { /* ... */ }\n\n    done() { /* ... */ }\n\n}\n```\n\n## Dependencies\n[babel-cli](https://www.npmjs.com/package/babel-cli) * \n[babel-plugin-transform-object-rest-spread](https://www.npmjs.com/package/babel-plugin-transform-object-rest-spread) * \n[babel-polyfill](https://www.npmjs.com/package/babel-polyfill) * \n[babel-preset-es2015](https://www.npmjs.com/package/babel-preset-es2015) * \n[babel-preset-es2017](https://www.npmjs.com/package/babel-preset-es2017) * \n[colors](https://www.npmjs.com/package/colors) * \n[commander](https://www.npmjs.com/package/commander) * \n[deep-object-diff](https://www.npmjs.com/package/deep-object-diff) * \n[expect](https://www.npmjs.com/package/expect) * \n[image-diff](https://www.npmjs.com/package/image-diff) * \n[phantom](https://www.npmjs.com/package/phantom) * \n[recursive-readdir-sync](https://www.npmjs.com/package/recursive-readdir-sync) * \n[xmlbuilder](https://www.npmjs.com/package/xmlbuilder) * \n[express](https://www.npmjs.com/package/express) * \n[nodemon](https://www.npmjs.com/package/nodemon)\n\n## Note on Patches/Pull Requests\n\n1. Fork the project.\n2. Make your feature addition or bug fix.\n3. Send me a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuxter%2Fguit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuxter%2Fguit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuxter%2Fguit/lists"}