diff --git a/.eslintrc.js b/.eslintrc.js index 35d2c738..da2f17b3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,38 +1,31 @@ module.exports = { root: true, - plugins: [ - '@typescript-eslint', - 'eslint-comments', - "cypress" - ], + plugins: ["@typescript-eslint", "eslint-comments", "cypress"], env: { es6: true, node: true, - 'cypress/globals': true + "cypress/globals": true, }, extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:eslint-comments/recommended', - 'prettier' + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:eslint-comments/recommended", + "prettier", ], overrides: [ { - files: ['**.ts'], - parser: '@typescript-eslint/parser', + files: ["**.ts"], + parser: "@typescript-eslint/parser", parserOptions: { - sourceType: 'module', - project: [ - './tsconfig.json', - './packages/*/tsconfig.json', - ], + sourceType: "module", + project: ["./tsconfig.json", "./example/tsconfig.json"], tsconfigRootDir: __dirname, warnOnUnsupportedTypeScriptVersion: false, EXPERIMENTAL_useSourceOfProjectReferenceRedirect: true, }, rules: { - '@typescript-eslint/explicit-module-boundary-types': 'off' - } + "@typescript-eslint/explicit-module-boundary-types": "off", + }, }, ], }; diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index ef480f95..da275160 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -2,4 +2,4 @@ github: [FRSOURCE] patreon: frsource -custom: ['https://www.buymeacoffee.com/FRSOURCE'] +custom: ["https://www.buymeacoffee.com/FRSOURCE"] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e784ecb1..d8492561 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,10 +1,9 @@ --- name: Bug report about: Create a report to help us improve -title: '' +title: "" labels: bug -assignees: '' - +assignees: "" --- **Describe the bug** @@ -12,6 +11,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,9 +24,10 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Please complete the following information:** - - OS and version: [e.g. Windows 10 build. 19043.1319] - - Browser and version [e.g. chrome 22] - - Cypress version [e.g. 8.6.0] + +- OS and version: [e.g. Windows 10 build. 19043.1319] +- Browser and version [e.g. chrome 22] +- Cypress version [e.g. 8.6.0] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 11fc491e..d883b8f2 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,10 +1,9 @@ --- name: Feature request about: Suggest an idea for this project -title: '' +title: "" labels: enhancement -assignees: '' - +assignees: "" --- **Is your feature request related to a problem? Please describe.** diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 192c7e2b..188f1071 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: CI +name: CI on: pull_request_target: branches: @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16.x' + node-version: "16.x" - name: Remove git auth run: git config --unset http.https://github.com/.extraheader - name: Generate yarn cache-key @@ -52,7 +52,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16.x' + node-version: "16.x" - name: remove git auth run: git config --unset http.https://github.com/.extraheader - name: Configure Yarn cache @@ -79,7 +79,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16.x' + node-version: "16.x" - name: remove git auth run: git config --unset http.https://github.com/.extraheader - name: Configure Yarn cache @@ -110,7 +110,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16.x' + node-version: "16.x" - name: remove git auth run: git config --unset http.https://github.com/.extraheader - name: Configure Yarn cache @@ -149,7 +149,7 @@ jobs: git config --global user.email "$(git --no-pager log --format=format:'%ae' -n 1)" - uses: actions/setup-node@v3 with: - node-version: '16.x' + node-version: "16.x" - name: remove git auth run: git config --unset http.https://github.com/.extraheader - name: Configure Yarn cache diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..518f78b4 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +node_modules +dist +coverage +CHANGELOG.md +.yarnrc.yml +example/.yarnrc.yml +.yarn diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3c13aba..a71aa482 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,7 @@ Don’t hesitate to ask a question directly on the [discussions board](https://g - We have no preference about number of commits on the PR - they will be all squashed by GitHub while merging - When creating a new feature/plugin/integration: + - Make sure the feature is covered by tests - Provide a meaningful description. In most cases it would make sens to first open a issue with a suggestion, discuss about it and have it approved before working on it @@ -40,12 +41,14 @@ Don’t hesitate to ask a question directly on the [discussions board](https://g ## Development Setup <!-- textlint-disable spelling --> + You will need [Node.js](https://nodejs.org/en/) **version 16+** and [yarn](https://yarnpkg.com/getting-started/install). + <!-- textlint-enable --> After cloning the repository, run: -``` bash +```bash yarn i # installs the project dependencies cd example && yarn i # install dependencies for example project (useful for testing) ``` @@ -58,7 +61,7 @@ Commit messages should follow the [conventional commits v1.0.0](https://www.conv When fired in the project root they will run corresponding actions in every nested package at once. -``` bash +```bash # build the project for NPM and example usage $ yarn build diff --git a/README.md b/README.md index 68060a6b..96acb787 100644 --- a/README.md +++ b/README.md @@ -71,54 +71,63 @@ npm install --save-dev @frsource/cypress-plugin-visual-regression-diff Next, you need to import the library: - first, in your support file (located by default in `cypress/support/index.js`): + ```ts // typescript / ES6 -import '@frsource/cypress-plugin-visual-regression-diff'; +import "@frsource/cypress-plugin-visual-regression-diff"; // javascript -require('@frsource/cypress-plugin-visual-regression-diff'); +require("@frsource/cypress-plugin-visual-regression-diff"); ``` - secondly: - (for Cypress 10.0+) in `cypress.config.js` (or `cypress.config.ts`): + ```ts // typescript / ES6 -import { defineConfig } from 'cypress'; -import { initPlugin } from '@frsource/cypress-plugin-visual-regression-diff/plugins'; +import { defineConfig } from "cypress"; +import { initPlugin } from "@frsource/cypress-plugin-visual-regression-diff/plugins"; export default defineConfig({ // initPlugin must be called in the section where it is used: e2e or component e2e: { setupNodeEvents(on, config) { initPlugin(on, config); - } + }, }, component: { setupNodeEvents(on, config) { initPlugin(on, config); - } - } + }, + }, }); ``` - - (for Cypress <10.0) in your plugins file (located by default in `cypress/plugins/index.js`): + +- (for Cypress <10.0) in your plugins file (located by default in `cypress/plugins/index.js`): + ```ts // typescript / ES6 -import { initPlugin } from '@frsource/cypress-plugin-visual-regression-diff/plugins'; +import { initPlugin } from "@frsource/cypress-plugin-visual-regression-diff/plugins"; -export default function (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) { +export default function ( + on: Cypress.PluginEvents, + config: Cypress.PluginConfigOptions +) { initPlugin(on, config); return config; -}; +} // javascript -const { initPlugin } = require('@frsource/cypress-plugin-visual-regression-diff/plugins'); +const { + initPlugin, +} = require("@frsource/cypress-plugin-visual-regression-diff/plugins"); module.exports = function (on, config) { initPlugin(on, config); return config; -} +}; ``` That's it - now let's see how to use the library in [usage section](#usage). @@ -128,7 +137,7 @@ That's it - now let's see how to use the library in [usage section](#usage). Once installed, the library might be used by writing in your test: ```ts -cy.get('.an-element-of-your-choice').matchImage(); +cy.get(".an-element-of-your-choice").matchImage(); ``` Or, if you would like to make a screenshot of whole document: @@ -184,7 +193,7 @@ cy.matchImage({ // maximum threshold above which the test should fail // default: 0.01 maxDiffThreshold: 0.1, - // forces scale factor to be set as value "1" + // forces scale factor to be set as value "1" // helps with screenshots being scaled 2x on high-density screens like Mac Retina // default: true forceDeviceScaleFactor: false, @@ -206,16 +215,15 @@ npx cypress run --env "pluginVisualRegressionUpdateImages=true,pluginVisualRegre ```ts // cypress.config.ts -import { defineConfig } from 'cypress'; +import { defineConfig } from "cypress"; export default defineConfig({ env: { pluginVisualRegressionUpdateImages: true, - pluginVisualRegressionDiffConfig: { threshold: 0.01 } - } -}) + pluginVisualRegressionDiffConfig: { threshold: 0.01 }, + }, +}); { - } ``` @@ -235,8 +243,8 @@ For more ways of setting environment variables [take a look here](https://docs.c Screenshots in Cypress do not scale to the viewport size by default. You can change this behavior: -* globally, by changing default screenshot configuration: <code>Cypress.Screenshot.defaults({ capture: 'viewport' });</code> -* locally, by passing screenshot configuration directly to the <code>.matchImage</code> command: <code>cy.matchImage({ screenshotConfig: { capture: 'viewport' } });</code> +- globally, by changing default screenshot configuration: <code>Cypress.Screenshot.defaults({ capture: 'viewport' });</code> +- locally, by passing screenshot configuration directly to the <code>.matchImage</code> command: <code>cy.matchImage({ screenshotConfig: { capture: 'viewport' } });</code> </details> diff --git a/__tests__/fixtures/prepare-screenshot-for-cleanup.spec.cy.js b/__tests__/fixtures/prepare-screenshot-for-cleanup.spec.cy.js index a6d416ee..63455cdf 100644 --- a/__tests__/fixtures/prepare-screenshot-for-cleanup.spec.cy.js +++ b/__tests__/fixtures/prepare-screenshot-for-cleanup.spec.cy.js @@ -1,6 +1,6 @@ -describe('Cleanup test', () => { - it('Create screenshot to be removed', () => { - cy.visit('/'); +describe("Cleanup test", () => { + it("Create screenshot to be removed", () => { + cy.visit("/"); cy.get('[data-testid="description"]').matchImage(); }); }); diff --git a/example/cypress.config.js b/example/cypress.config.js deleted file mode 100644 index 89ee51b4..00000000 --- a/example/cypress.config.js +++ /dev/null @@ -1,24 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { defineConfig } = require("cypress"); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const { initPlugin } = require("@frsource/cypress-plugin-visual-regression-diff/dist/plugins"); - -module.exports = defineConfig({ - video: false, - e2e: { - setupNodeEvents(on, config) { - initPlugin(on, config); - }, - specPattern: "cypress/e2e/**/*.cy.{js,jsx,ts,tsx}" - }, - - component: { - setupNodeEvents(on, config) { - initPlugin(on, config); - }, - devServer: { - framework: "vue-cli", - bundler: "webpack", - }, - }, -}); diff --git a/example/cypress.config.ts b/example/cypress.config.ts new file mode 100644 index 00000000..c3f8c966 --- /dev/null +++ b/example/cypress.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from "cypress"; +import { initPlugin } from "@frsource/cypress-plugin-visual-regression-diff/plugins"; + +module.exports = defineConfig({ + video: false, + e2e: { + setupNodeEvents(on, config) { + initPlugin(on, config); + }, + specPattern: "cypress/e2e/**/*.cy.{js,jsx,ts,tsx}", + }, + + component: { + setupNodeEvents(on, config) { + initPlugin(on, config); + }, + devServer: { + framework: "vue-cli", + bundler: "webpack", + }, + }, +}); diff --git a/example/cypress/component/HelloWorld.cy.js b/example/cypress/component/HelloWorld.cy.js deleted file mode 100644 index e4c3eacc..00000000 --- a/example/cypress/component/HelloWorld.cy.js +++ /dev/null @@ -1,16 +0,0 @@ -import HelloWorld from '../../src/components/HelloWorld.vue'; - -const msg = 'Some random test message'; - -describe('HelloWorld.cy.js', () => { - it('playground', () => { - cy.mount(HelloWorld, { - propsData: { msg }, - }) - .then(() => { - cy.contains('h1', msg); - cy.matchImage(); - cy.get('[data-testid="description"]').matchImage(); - }) - }) -}) diff --git a/example/cypress/component/HelloWorld.cy.ts b/example/cypress/component/HelloWorld.cy.ts new file mode 100644 index 00000000..ed8d5cf6 --- /dev/null +++ b/example/cypress/component/HelloWorld.cy.ts @@ -0,0 +1,16 @@ +import { mount } from "cypress/vue"; +import HelloWorld from "../../src/components/HelloWorld.vue"; + +const msg = "Some random test message"; + +describe("HelloWorld.cy.js", () => { + it("playground", () => { + mount(HelloWorld, { + propsData: { msg }, + }).then(() => { + cy.contains("h1", msg); + cy.matchImage(); + cy.get('[data-testid="description"]').matchImage(); + }); + }); +}); diff --git a/example/cypress/e2e/spec.cy.js b/example/cypress/e2e/spec.cy.js deleted file mode 100644 index 4671caf8..00000000 --- a/example/cypress/e2e/spec.cy.js +++ /dev/null @@ -1,11 +0,0 @@ -describe('My First Test', () => { - it('Visits the app root url', () => { - cy.visit('/') - cy.contains('h1', 'Welcome to Your Vue.js App') - cy.matchImage() - .then(({ imgNewPath }) => { - // match against image from custom path - cy.matchImage({ matchAgainstPath: imgNewPath }); - }) - }) -}) diff --git a/example/cypress/e2e/spec.cy.ts b/example/cypress/e2e/spec.cy.ts new file mode 100644 index 00000000..c6555cd3 --- /dev/null +++ b/example/cypress/e2e/spec.cy.ts @@ -0,0 +1,10 @@ +describe("My First Test", () => { + it("Visits the app root url", () => { + cy.visit("/"); + cy.contains("h1", "Welcome to Your Vue.js App"); + cy.matchImage().then(({ imgNewPath }) => { + // match against image from custom path + cy.matchImage({ matchAgainstPath: imgNewPath }); + }); + }); +}); diff --git a/example/cypress/support/commands.js b/example/cypress/support/commands.ts similarity index 92% rename from example/cypress/support/commands.js rename to example/cypress/support/commands.ts index 6344a6d2..f907400a 100644 --- a/example/cypress/support/commands.js +++ b/example/cypress/support/commands.ts @@ -24,4 +24,4 @@ // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -import '@frsource/cypress-plugin-visual-regression-diff/dist/support'; +import "@frsource/cypress-plugin-visual-regression-diff/support"; diff --git a/example/cypress/support/component-index.html b/example/cypress/support/component-index.html index ac6e79fd..e39ba429 100644 --- a/example/cypress/support/component-index.html +++ b/example/cypress/support/component-index.html @@ -1,12 +1,12 @@ <!DOCTYPE html> <html> <head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width,initial-scale=1.0"> + <meta charset="utf-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <title>Components App</title> </head> <body> <div data-cy-root></div> </body> -</html> \ No newline at end of file +</html> diff --git a/example/cypress/support/e2e.js b/example/cypress/support/component.ts similarity index 96% rename from example/cypress/support/e2e.js rename to example/cypress/support/component.ts index 5e450a7b..4d17a4a4 100644 --- a/example/cypress/support/e2e.js +++ b/example/cypress/support/component.ts @@ -14,7 +14,7 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands' +import "./commands"; // Alternatively you can use CommonJS syntax: // require('./commands') diff --git a/example/cypress/support/component.js b/example/cypress/support/e2e.ts similarity index 82% rename from example/cypress/support/component.js rename to example/cypress/support/e2e.ts index 0474d1b8..4d17a4a4 100644 --- a/example/cypress/support/component.js +++ b/example/cypress/support/e2e.ts @@ -14,14 +14,7 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands' +import "./commands"; // Alternatively you can use CommonJS syntax: // require('./commands') - -import { mount } from 'cypress/vue' - -Cypress.Commands.add('mount', mount); - -// Example use: -// cy.mount(MyComponent) diff --git a/example/package.json b/example/package.json index d1e21f09..d3b61a31 100644 --- a/example/package.json +++ b/example/package.json @@ -19,6 +19,7 @@ "@frsource/cypress-plugin-visual-regression-diff": "portal:..", "@vue/cli-plugin-e2e-cypress": "5.0.8", "@vue/cli-service": "5.0.8", - "cypress": "10.11.0" + "cypress": "10.11.0", + "typescript": "^4.8.4" } } diff --git a/example/public/index.html b/example/public/index.html index 3e5a1396..5f1393c1 100644 --- a/example/public/index.html +++ b/example/public/index.html @@ -1,15 +1,19 @@ <!DOCTYPE html> <html lang=""> <head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width,initial-scale=1.0"> - <link rel="icon" href="<%= BASE_URL %>favicon.ico"> + <meta charset="utf-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width,initial-scale=1.0" /> + <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> - <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> + <strong + >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work + properly without JavaScript enabled. Please enable it to + continue.</strong + > </noscript> <div id="app"></div> <!-- built files will be auto injected --> diff --git a/example/src/App.vue b/example/src/App.vue index 591a0312..57791b06 100644 --- a/example/src/App.vue +++ b/example/src/App.vue @@ -1,17 +1,17 @@ <template> - <img alt="Vue logo" src="./assets/logo.png"> - <HelloWorld msg="Welcome to Your Vue.js App"/> + <img alt="Vue logo" src="./assets/logo.png" /> + <HelloWorld msg="Welcome to Your Vue.js App" /> </template> <script> -import HelloWorld from './components/HelloWorld.vue' +import HelloWorld from "./components/HelloWorld.vue"; export default { - name: 'App', + name: "App", components: { - HelloWorld - } -} + HelloWorld, + }, +}; </script> <style> diff --git a/example/src/components/HelloWorld.vue b/example/src/components/HelloWorld.vue index bd5c6c14..fbfca69a 100644 --- a/example/src/components/HelloWorld.vue +++ b/example/src/components/HelloWorld.vue @@ -2,40 +2,89 @@ <div> <h1>{{ msg }}</h1> <p data-testid="description"> - For a guide and recipes on how to configure / customize this project,<br> + For a guide and recipes on how to configure / customize this project,<br /> check out the - <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>. + <a href="https://cli.vuejs.org" target="_blank" rel="noopener" + >vue-cli documentation</a + >. </p> <h3>Installed CLI Plugins</h3> <ul> - <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-cypress" target="_blank" rel="noopener">e2e-cypress</a></li> + <li> + <a + href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-e2e-cypress" + target="_blank" + rel="noopener" + >e2e-cypress</a + > + </li> </ul> <h3>Essential Links</h3> <ul> - <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li> - <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li> - <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li> - <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li> - <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li> + <li> + <a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a> + </li> + <li> + <a href="https://forum.vuejs.org" target="_blank" rel="noopener" + >Forum</a + > + </li> + <li> + <a href="https://chat.vuejs.org" target="_blank" rel="noopener" + >Community Chat</a + > + </li> + <li> + <a href="https://twitter.com/vuejs" target="_blank" rel="noopener" + >Twitter</a + > + </li> + <li> + <a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a> + </li> </ul> <h3>Ecosystem</h3> <ul> - <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> - <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> - <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li> - <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> - <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li> + <li> + <a href="https://router.vuejs.org" target="_blank" rel="noopener" + >vue-router</a + > + </li> + <li> + <a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a> + </li> + <li> + <a + href="https://github.com/vuejs/vue-devtools#vue-devtools" + target="_blank" + rel="noopener" + >vue-devtools</a + > + </li> + <li> + <a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener" + >vue-loader</a + > + </li> + <li> + <a + href="https://github.com/vuejs/awesome-vue" + target="_blank" + rel="noopener" + >awesome-vue</a + > + </li> </ul> </div> </template> <script> export default { - name: 'HelloWorld', + name: "HelloWorld", props: { - msg: String - } -} + msg: String, + }, +}; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> diff --git a/example/src/main.js b/example/src/main.js index 01433bca..b670de8b 100644 --- a/example/src/main.js +++ b/example/src/main.js @@ -1,4 +1,4 @@ -import { createApp } from 'vue' -import App from './App.vue' +import { createApp } from "vue"; +import App from "./App.vue"; -createApp(App).mount('#app') +createApp(App).mount("#app"); diff --git a/example/jsconfig.json b/example/tsconfig.json similarity index 54% rename from example/jsconfig.json rename to example/tsconfig.json index 4aafc5f6..b6bd4c8d 100644 --- a/example/jsconfig.json +++ b/example/tsconfig.json @@ -5,15 +5,8 @@ "baseUrl": "./", "moduleResolution": "node", "paths": { - "@/*": [ - "src/*" - ] + "@/*": ["src/*"] }, - "lib": [ - "esnext", - "dom", - "dom.iterable", - "scripthost" - ] + "lib": ["esnext", "dom", "dom.iterable", "scripthost"] } } diff --git a/example/yarn.lock b/example/yarn.lock index 1a3bfd88..24d05808 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -2890,6 +2890,7 @@ __metadata: "@vue/cli-plugin-e2e-cypress": 5.0.8 "@vue/cli-service": 5.0.8 cypress: 10.11.0 + typescript: ^4.8.4 vue: 3.2.41 languageName: unknown linkType: soft @@ -7046,6 +7047,26 @@ __metadata: languageName: node linkType: hard +"typescript@npm:^4.8.4": + version: 4.8.4 + resolution: "typescript@npm:4.8.4" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 3e4f061658e0c8f36c820802fa809e0fd812b85687a9a2f5430bc3d0368e37d1c9605c3ce9b39df9a05af2ece67b1d844f9f6ea8ff42819f13bcb80f85629af0 + languageName: node + linkType: hard + +"typescript@patch:typescript@^4.8.4#~builtin<compat/typescript>": + version: 4.8.4 + resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin<compat/typescript>::version=4.8.4&hash=701156" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 301459fc3eb3b1a38fe91bf96d98eb55da88a9cb17b4ef80b4d105d620f4d547ba776cc27b44cc2ef58b66eda23fe0a74142feb5e79a6fb99f54fc018a696afa + languageName: node + linkType: hard + "unique-filename@npm:^1.1.1": version: 1.1.1 resolution: "unique-filename@npm:1.1.1" diff --git a/package.json b/package.json index 2bef4243..71fcd456 100644 --- a/package.json +++ b/package.json @@ -33,14 +33,27 @@ }, "./*": "./*.js" }, + "typesVersions": { + "*": { + "support": [ + "dist/support.d.ts" + ], + "plugins": [ + "dist/plugins.d.ts" + ], + "constants": [ + "dist/constants.d.ts" + ] + } + }, "license": "MIT", "scripts": { "build": "del-cli dist && microbundle src/{support,plugins,constants}.ts --target node --tsconfig tsconfig.build.json -f cjs,modern && cpy 'dist/src/*' dist && del-cli dist/src \"dist/*.{hook,utils}.d.ts\"", "lint": "eslint '**/*.ts' --ignore-pattern '**/*.d.ts'", "lint:fix": "yarn lint --fix", "lint:ci": "yarn lint --max-warnings 0", - "prettify": "prettier --write src", - "prettify:ci": "prettier --check src", + "prettify": "prettier --write .", + "prettify:ci": "prettier --check .", "prepack": "yarn build", "release": "semantic-release", "release:ci": "yarn release --yes", diff --git a/release.config.js b/release.config.js index 02cc3597..78d78f02 100644 --- a/release.config.js +++ b/release.config.js @@ -1,19 +1,25 @@ module.exports = { - "branches": ["main"], - "plugins": [ - ["@semantic-release/commit-analyzer", { - "releaseRules": [ - {"type": "chore", "scope": "deps", "release": "patch"}, - {"type": "docs", "release": "patch"} - ] - }], - "@semantic-release/release-notes-generator", - "@semantic-release/github", - "@semantic-release/changelog", - ["@semantic-release/npm", { - "tarballDir": "release" - }], - "@semantic-release/git" + branches: ["main"], + plugins: [ + [ + "@semantic-release/commit-analyzer", + { + releaseRules: [ + { type: "chore", scope: "deps", release: "patch" }, + { type: "docs", release: "patch" }, + ], + }, ], - "preset": "angular" + "@semantic-release/release-notes-generator", + "@semantic-release/github", + "@semantic-release/changelog", + [ + "@semantic-release/npm", + { + tarballDir: "release", + }, + ], + "@semantic-release/git", + ], + preset: "angular", }; diff --git a/renovate.json b/renovate.json index ac239a16..8d4f8d54 100644 --- a/renovate.json +++ b/renovate.json @@ -1,9 +1,7 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "timezone": "Europe/Warsaw", - "extends": [ - "config:base" - ], + "extends": ["config:base"], "packageRules": [ { "extends": "packages:linters", @@ -23,27 +21,17 @@ }, { "groupName": "definitelyTyped", - "matchPackagePrefixes": [ - "@types/" - ], + "matchPackagePrefixes": ["@types/"], "automerge": true, "automergeType": "branch" }, { "groupName": "vitest", - "matchPackagePrefixes": [ - "@vitest/", - "vitest" - ] + "matchPackagePrefixes": ["@vitest/", "vitest"] }, { - "matchPackagePatterns": [ - "*" - ], - "matchUpdateTypes": [ - "minor", - "patch" - ], + "matchPackagePatterns": ["*"], + "matchUpdateTypes": ["minor", "patch"], "groupName": "all non-major dependencies", "groupSlug": "all-minor-patch", "automerge": true, diff --git a/src/commands.ts b/src/commands.ts index 3c12a8ab..d189443c 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -17,15 +17,34 @@ declare global { imagesPath?: string; maxDiffThreshold?: number; title?: string; + matchAgainstPath?: string; + // IDEA: to be implemented if support for files NOT from filesystem needed + // matchAgainst?: string | Buffer; }; + type MatchImageReturn = { + diffValue: number | undefined; + imgNewPath: string; + imgPath: string; + imgDiffPath: string; + imgNewBase64: string | undefined; + imgBase64: string | undefined; + imgDiffBase64: string | undefined; + imgNew: InstanceType<Cypress["Buffer"]> | undefined; + img: InstanceType<Cypress["Buffer"]> | undefined; + imgDiff: InstanceType<Cypress["Buffer"]> | undefined; + }; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Chainable<Subject> { /** * Command to create and compare image snapshots. * @memberof Cypress.Chainable * @example cy.get('.my-element').matchImage(); */ - matchImage(options?: Cypress.MatchImageOptions): Chainable<Subject>; + matchImage( + options?: Cypress.MatchImageOptions + ): Chainable<MatchImageReturn>; } } } @@ -90,6 +109,7 @@ export const getConfig = (options: Cypress.MatchImageOptions) => { | Partial<Cypress.ScreenshotDefaultsOptions> | undefined) || {}, + matchAgainstPath: options.matchAgainstPath || undefined, }; }; @@ -107,6 +127,7 @@ Cypress.Commands.add( maxDiffThreshold, diffConfig, screenshotConfig, + matchAgainstPath, } = getConfig(options); return cy @@ -143,7 +164,8 @@ Cypress.Commands.add( { scaleFactor, imgNew: imgPath, - imgOld: imgPath.replace(FILE_SUFFIX.actual, ""), + imgOld: + matchAgainstPath || imgPath.replace(FILE_SUFFIX.actual, ""), updateImages, maxDiffThreshold, diffConfig, @@ -191,6 +213,28 @@ Cypress.Commands.add( log.set("consoleProps", () => res); throw constructCypressError(log, new Error(res.message)); } + + return { + diffValue: res.imgDiff, + imgNewPath: imgPath, + imgPath: imgPath.replace(FILE_SUFFIX.actual, ""), + imgDiffPath: imgPath.replace(FILE_SUFFIX.actual, FILE_SUFFIX.diff), + imgNewBase64: res.imgNewBase64, + imgBase64: res.imgOldBase64, + imgDiffBase64: res.imgDiffBase64, + imgNew: + typeof res.imgNewBase64 === "string" + ? Cypress.Buffer.from(res.imgNewBase64, "base64") + : undefined, + img: + typeof res.imgOldBase64 === "string" + ? Cypress.Buffer.from(res.imgOldBase64, "base64") + : undefined, + imgDiff: + typeof res.imgDiffBase64 === "string" + ? Cypress.Buffer.from(res.imgDiffBase64, "base64") + : undefined, + }; }); } ); diff --git a/vitest.config.ts b/vitest.config.ts index 62e884a8..05a1bc81 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,9 +1,15 @@ -import { defineConfig, configDefaults } from 'vitest/config'; -import tsconfigPaths from 'vite-tsconfig-paths'; -import path from 'path'; +import { defineConfig, configDefaults } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; +import path from "path"; -const exludeFiles = [...configDefaults.exclude, 'src/assets/*', 'example', '.yarn', '*.js']; -const testsGlob = 'src/**.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'; +const exludeFiles = [ + ...configDefaults.exclude, + "src/assets/*", + "example", + ".yarn", + "*.js", +]; +const testsGlob = "src/**.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"; const isCI = !!process.env.CI; @@ -13,16 +19,16 @@ export default defineConfig({ exclude: exludeFiles, include: [testsGlob], coverage: { - provider: 'c8', - reporter: isCI ? ['text', 'lcovonly'] : ['text', 'lcov'], + provider: "c8", + reporter: isCI ? ["text", "lcovonly"] : ["text", "lcov"], lines: 90, functions: 90, branches: 90, statements: 90, }, alias: { - '@fixtures/*': path.resolve(__dirname, '__tests__', 'partials'), - '@mocks/*': path.resolve(__dirname, '__tests__', 'mocks') - } + "@fixtures/*": path.resolve(__dirname, "__tests__", "partials"), + "@mocks/*": path.resolve(__dirname, "__tests__", "mocks"), + }, }, }); diff --git a/yarn.lock b/yarn.lock index c9e54c90..528d0f4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3473,9 +3473,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001286, caniuse-lite@npm:^1.0.30001297": - version: 1.0.30001298 - resolution: "caniuse-lite@npm:1.0.30001298" - checksum: 43566732d1b8746e3dfae57f558471c701b26b2c166fb9fc53ad750d83128b2eb680a5e08233717e64055779b408c72d3b2cfad6d4ae33a3e647a11dc1c0d515 + version: 1.0.30001429 + resolution: "caniuse-lite@npm:1.0.30001429" + checksum: d1658080248ef5ef0f5157423b2766026e6aa45642ce3b2cc74859b6a54e39881dd902397a2368324ed30ed0cd40250f11a4a4f3773453cd57b88db5e5e5c76a languageName: node linkType: hard