{"id":13393367,"url":"https://github.com/NimaSoroush/differencify","last_synced_at":"2025-03-13T19:31:33.620Z","repository":{"id":59342432,"uuid":"94310798","full_name":"NimaSoroush/differencify","owner":"NimaSoroush","description":"Differencify is a library for visual regression testing","archived":false,"fork":false,"pushed_at":"2020-06-02T12:59:51.000Z","size":6931,"stargazers_count":635,"open_issues_count":27,"forks_count":46,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-12T12:06:36.343Z","etag":null,"topics":["headless-chrome","jest","nodejs","puppeteer","visual-regression-testing","visual-testing"],"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/NimaSoroush.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-14T08:57:08.000Z","updated_at":"2025-03-02T12:10:17.000Z","dependencies_parsed_at":"2022-09-24T21:30:22.102Z","dependency_job_id":null,"html_url":"https://github.com/NimaSoroush/differencify","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimaSoroush%2Fdifferencify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimaSoroush%2Fdifferencify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimaSoroush%2Fdifferencify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimaSoroush%2Fdifferencify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NimaSoroush","download_url":"https://codeload.github.com/NimaSoroush/differencify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243469162,"owners_count":20295699,"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":["headless-chrome","jest","nodejs","puppeteer","visual-regression-testing","visual-testing"],"created_at":"2024-07-30T17:00:51.271Z","updated_at":"2025-03-13T19:31:33.593Z","avatar_url":"https://github.com/NimaSoroush.png","language":"JavaScript","readme":"\u003cp align=\"center\"\u003e\u003cimg alt=\"Differencify\" src=\"images/logo.gif\" width=\"150\"\u003e\n\u003cbr\u003e\n\u003cstrong\u003eDifferencify \u003cimg src=\"images/logo.png\" width=\"30\" height=\"30\"\u003e\u003c/strong\u003e\n\u003cbr\u003e\nRegression Testing suite!\n\u003c/p\u003e\n\u003cbr\u003e\n\n[![CircleCI](https://circleci.com/gh/NimaSoroush/differencify/tree/master.svg?style=svg)](https://circleci.com/gh/NimaSoroush/differencify/tree/master)\n[![npm version](https://badge.fury.io/js/differencify.svg)](https://badge.fury.io/js/differencify) [![Greenkeeper badge](https://badges.greenkeeper.io/NimaSoroush/differencify.svg)](https://greenkeeper.io/)\n\u003ca href=\"https://github.com/jest-community/awesome-jest\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/974d19bae442ae2c1657753f39651ade6bef3411/68747470733a2f2f617765736f6d652e72652f6d656e74696f6e65642d62616467652e737667\" alt=\"Mentioned in Awesome Jest\" data-canonical-src=\"https://awesome.re/mentioned-badge.svg\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n\n## About\nDifferencify is a library for visual regression testing via comparing your local changes with reference screenshots of your website. It is built on top of chrome headless using [Puppeteer](https://github.com/GoogleChrome/puppeteer).\n\n|Reference|Local changes|\n|---------|-------------|\n|\u003cimg alt=\"Differencify\" src=\"images/reference_screenshot.png\" width=\"400\"\u003e|\u003cimg alt=\"Differencify\" src=\"images/differencified_screenshot.png\" width=\"400\"\u003e|\n\n## How it works\n\u003cp align=\"center\"\u003e\u003cimg alt=\"Differencify\" src=\"images/workflow.png\" width=\"400\"\u003e\u003c/p\u003e\n\n\n## Installation\n\u003e *Note: Differencify uses async/await and targets Node v7.6.0 or greater*\n\nInstall the module:\n```bash\nnpm install differencify\n```\n## Usage\n```js\nconst Differencify = require('differencify');\nconst differencify = new Differencify(GlobalOptions);\n```\n\nDifferencify matches [Puppeteer](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md)'s API completely. Look at [API.md](API.md) for more details.\n\n### Validate your changes\n```js\n(async () =\u003e {\n  const result = await differencify\n    .init(TestOptions)\n    .launch()\n    .newPage()\n    .setViewport({ width: 1600, height: 1200 })\n    .goto('https://github.com/NimaSoroush/differencify')\n    .waitFor(1000)\n    .screenshot()\n    .toMatchSnapshot()\n    .result((result) =\u003e {\n      console.log(result); // Prints true or false\n    })\n    .close()\n    .end();\n\n  // or unchained\n\n  const target = differencify.init({ chain: false });\n  await target.launch();\n  const page = await target.newPage();\n  await page.setViewport({ width: 1600, height: 1200 });\n  await page.goto('https://github.com/NimaSoroush/differencify');\n  await page.waitFor(1000);\n  const image = await page.screenshot();\n  const result = await target.toMatchSnapshot(image)\n  await page.close();\n  await target.close();\n\n  console.log(result); // Prints true or false\n})();\n```\nSee more examples [here](API.md)\n\n## Usage with \u003cspan style=\"color:#930a36\"\u003eJEST\u003c/span\u003e\u003cimg src=\"images/jest.svg\" width=\"50\" height=\"50\"\u003e\n\nOnly need to wrap your steps into `it()` function\n```js\nconst differencify = new Differencify();\ndescribe('tests differencify', () =\u003e {\n  it('validate github page appear correctly', async () =\u003e {\n    await differencify\n      .init()\n      .launch()\n      .newPage()\n      .goto('https://github.com/NimaSoroush/differencify')\n      .screenshot()\n      .toMatchSnapshot()\n      .close()\n      .end();\n  });\n});\n```\nAs you can see, you don't need to return `result` as `toMatchSnapshot` will automatically validate the result. See more jest examples [here](src/integration.tests/integration.test.js).\n\n### Test \u003cspan style=\"color:green\"\u003ePASS\u003c/span\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/test-pass.png\" width=\"500\"\u003e\n\u003c/p\u003e\n\n### Test \u003cspan style=\"color:red\"\u003eFAIL\u003c/span\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/test-fail.png\" width=\"500\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/test-dir.png\" width=\"500\"\u003e\n\u003c/p\u003e\n\nSame way as Jest [snapshots testing](http://facebook.github.io/jest/docs/en/snapshot-testing.html), to update the snapshots, run jest with `--updateSnapshot` or `-u` argument.\n\n## Jest reporter\n\nYou can generate an index document of the saved images by using the differencify jest reporter.\n\n```bash\n$ npm i -D differencify-jest-reporter\n```\n\nEnable the reporter in your jest config:\n\n```\nmodule.exports = {\n  reporters: [\n    'default', // keep the default reporter\n    [\n      'differencify-jest-reporter',\n      {\n        debug: true,\n        reportPath: 'differencify_reports', // relative to root of project\n        reportTypes: {\n          html: 'index.html',\n          json: 'index.json',\n        },\n      },\n    ],\n  ],\n};\n```\n\nAlternatively, enable the reporter with the cli:\n\n```\njest --reporters default differencify-jest-reporter\n```\n\n### Jest reporter output\n\u003cp align=\"center\"\u003e\u003cimg alt=\"differencify-report\" src=\"images/differencify-report.png\" width=\"500\"\u003e\u003c/p\u003e\n\n## Usage with other test frameworks\nIf you are using other test frameworks you can still validate your tests. Differencify will return `true` or `false` by the end of execution. This can be used to assert on. See this [example](https://github.com/NimaSoroush/differencify#validate-your-changes).\n\nTo Create/Update reference screenshots, simply set environment variable `update=true` and run the same code.\n\n```\n\u003e update=true node test.js\n```\n\n## Mocking browser requests\nDifferencify uses [Mockeer](https://github.com/NimaSoroush/Mockeer) to run chrome headless browser in isolation. This will help with more consistent and stable results when it comes dealing with a website that has inconsistent downstream dependencies. (e.g. unique API call returns different results based on request time). More details [here](https://github.com/NimaSoroush/Mockeer)\n\nTo use this feature call `mockRequests` during your tests.\n\n```js\n(async () =\u003e {\n  const result = await differencify\n    .init(TestOptions)\n    .launch()\n    .newPage()\n    .mockRequests()\n    .goto('https://github.com/NimaSoroush/differencify')\n    .screenshot()\n    .toMatchSnapshot()\n    .result((result) =\u003e {\n      console.log(result);\n    })\n    .close()\n    .end();\n\n  // or unchained\n\n  const target = differencify.init({ chain: false });\n  await target.launch();\n  const page = await target.newPage();\n  await target.mockRequests();\n  await page.goto('https://github.com/NimaSoroush/differencify');\n  const image = await page.screenshot();\n  const result = await target.toMatchSnapshot(image)\n  await page.close();\n  await target.close();\n\n  console.log(result);\n})();\n```\nMore examples [here](src/integration.tests/integration.test.js)\n\n## Debugging\nIt is possible to debug your tests execution by passing `debug:true` as global config in Differencify class. See full list of configs [below](https://github.com/NimaSoroush/differencify#globaloptions)\n\n```js\nconst differencify = new Differencify({ debug: true });\n```\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/test.gif\" width=\"500\"\u003e\n\u003c/p\u003e\n\n## Visible mode\nBy default differencify runs chrome in headless mode. If you want to see the browser in non-headless mode set `headless:false` when launching the browser. See more details [here](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).\n\n```js\nconst differencify = new Differencify();\n(async () =\u003e {\n  await differencify\n    .init()\n    .launch({ headless: false })\n    .newPage()\n    .goto('https://github.com/NimaSoroush/differencify')\n    .screenshot()\n    .toMatchSnapshot()\n    .close()\n    .end();\n})();\n```\n\n\n## API\n\nSee [API.md](API.md) for a full list of API calls and examples.\n\n## GlobalOptions\n\n|Parameter|type|required|description|default|\n|---------|----|--------|-----------|-------|\n|`debug`|`boolean`|no|Enables console output|false|\n|`imageSnapshotPath`|`string`|no|Stores reference screenshots in this directory|./differencify_reports|\n|`saveDifferencifiedImage`|`boolean`|no|Save differencified image to test report path in case of mismatch|true|\n|`saveCurrentImage`|`boolean`|no|Save the captured image from current test run to test report path|true|\n|`mismatchThreshold`|`number`|no|Difference tolerance between reference/test image|0.001|\n\n## TestOptions\n\n|Parameter|type|required|description|default|\n|---------|----|--------|-----------|-------|\n|`testName`|`string`|no|Unique name for your test case|test|\n|`chain`|`boolean`|no|Whether to chain differencify commands or not. See [API.md](API.md) for more details|true|\n\n## Steps API\n\nSee [API.md](API.md) for a full list of API calls and examples.\n\n\n## Interested on Docker image!\n\nA [Docker base image](https://hub.docker.com/r/nimasoroush/differencify/) is available for local and CI usage based on this [Dockerfile](Docker/Dockerfile). To see an example look at this [Dockerfile](Dockerfile).\n\nUsage:\n\n```\nFROM nimasoroush/differencify\nRUN npm install differencify\n...\n```\n\n\n## Links\n\nSee the [integration test example](./src/integration.tests) for working usages and CI integration with jest, and mock examples in [API.md](API.md)\n\nVisit project [Gitter Chat](https://gitter.im/differencify/QA) for general Q/A around project\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) if you want to contribute.\n\nRead [this article](https://medium.com/@nima.soroush.h/make-visual-regression-testing-easier-4a3dc7073737) that explain simple usage of this library\n\nArticle about how to use [Differencify in Docker](https://medium.com/@nima.soroush.h/using-differencify-in-docker-and-ci-99e3d1ec057c)\n\n[Gist example](https://gist.github.com/NimaSoroush/28c3a5808af393610a33bd32d4c43911) with vanilla node\n","funding_links":[],"categories":["Packages","Opensource projects","JavaScript","包","Tools and frameworks (a-z↓)","Tools and frameworks","Web App Testing"],"sub_categories":["Snapshot","贡献","Differencify"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNimaSoroush%2Fdifferencify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNimaSoroush%2Fdifferencify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNimaSoroush%2Fdifferencify/lists"}