diff --git a/.github/screenshot-bot.config.toml b/.github/screenshot-bot.config.toml index 7451ce7fa1e0..a161201598bf 100644 --- a/.github/screenshot-bot.config.toml +++ b/.github/screenshot-bot.config.toml @@ -22,4 +22,4 @@ branchesIgnore = ["^release/.*", "^v[0-9].x$"] screenshotImageAttrs = [] # Text which is placed at the beginning of section "Failed tests" -failedTestsReportDescription = '**After <= Diff => Before**' +failedTestsReportDescription = '**Before <= Diff => After**' diff --git a/.github/workflows/e2e-playwright.yml b/.github/workflows/e2e-playwright.yml index dba9900f9638..b006c4942b20 100644 --- a/.github/workflows/e2e-playwright.yml +++ b/.github/workflows/e2e-playwright.yml @@ -74,7 +74,7 @@ jobs: - name: Combine images to get diff reports run: | npm install canvas - npx ts-node ./scripts/combine-playwright-failed-screenshots.ts + npx ts-node ./scripts/visual-testing/combine-playwright-failed-screenshots.ts - name: Debug output continue-on-error: true diff --git a/.gitignore b/.gitignore index 1d8f4f3cd00c..adda93a4193f 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ RELEASE_BODY.md *tsbuildinfo .angular .nx +/projects/demo-cypress/tests-results/ /projects/demo-playwright/tests-results/ /projects/demo-playwright/tests-report/ /projects/demo-playwright/snapshots/ diff --git a/package-lock.json b/package-lock.json index e9434a70b275..95691b5b865c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,7 +46,7 @@ "ng-packagr": "16.2.3", "ngx-highlightjs": "10.0.0", "nx": "19.8.2", - "rxjs": "7.5.0", + "rxjs": "7.8.1", "standard-version": "9.5.0", "ts-mockito": "2.6.1", "ts-node": "10.9.2", @@ -405,16 +405,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/architect/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@angular-devkit/build-angular": { "version": "16.2.16", "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.2.16.tgz", @@ -666,16 +656,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -769,16 +749,6 @@ "webpack-dev-server": "^4.0.0" } }, - "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@angular-devkit/core": { "version": "16.2.16", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.16.tgz", @@ -807,16 +777,6 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@angular-devkit/schematics": { "version": "16.2.16", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.16.tgz", @@ -859,16 +819,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@angular-eslint/bundled-angular-compiler": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.3.1.tgz", @@ -3817,7 +3767,6 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "license": "MIT", - "optional": true, "engines": { "node": ">=0.1.90" } @@ -9345,16 +9294,6 @@ "node": ">= 4" } }, - "node_modules/@nx/webpack/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@nx/webpack/node_modules/sass-loader": { "version": "12.6.0", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", @@ -17338,6 +17277,38 @@ "node": "^16.0.0 || ^18.0.0 || >=20.0.0" } }, + "node_modules/cypress-image-diff-js": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cypress-image-diff-js/-/cypress-image-diff-js-2.2.1.tgz", + "integrity": "sha512-ukZAiijQ54LLPefXDXfmscTcUn55QpB4LWEaxVEzZOlihHQyxGWzgT4cMO7jQ2d2rzwpIqxNWWUaAyjNHVyl/g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@colors/colors": "^1.5.0", + "arg": "^4.1.1", + "cypress-recurse": "^1.13.1", + "fs-extra": "^9.0.1", + "handlebars": "^4.7.7", + "lodash": "^4.17.21", + "pixelmatch": "^5.1.0", + "pngjs": "^3.4.0" + }, + "bin": { + "cypress-image-diff": "bin/cypress-image-diff.js" + }, + "peerDependencies": { + "cypress": ">=9.6.1" + } + }, + "node_modules/cypress-recurse": { + "version": "1.35.3", + "resolved": "https://registry.npmjs.org/cypress-recurse/-/cypress-recurse-1.35.3.tgz", + "integrity": "sha512-NbFOpEuZT4tFqAB0jQqel7WtVNDe8pvSHE2TfXvYk4pspf3wq98OC2RhhLn3bMnoCnPtY4IHO7e37c+CZ9HnMA==", + "dev": true, + "dependencies": { + "humanize-duration": "^3.27.3" + } + }, "node_modules/cypress/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -24101,6 +24072,12 @@ "node": ">=8.12.0" } }, + "node_modules/humanize-duration": { + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.32.1.tgz", + "integrity": "sha512-inh5wue5XdfObhu/IGEMiA1nUXigSGcaKNemcbLRKa7jXYGDZXr3LoT9pTIzq2hPEbld7w/qv9h+ikWGz8fL1g==", + "dev": true + }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -24470,16 +24447,6 @@ "node": ">=8" } }, - "node_modules/inquirer/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/inquirer/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -28777,16 +28744,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -30848,16 +30805,6 @@ "node": ">=12" } }, - "node_modules/ng-packagr/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/ngx-highlightjs": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/ngx-highlightjs/-/ngx-highlightjs-10.0.0.tgz", @@ -32692,6 +32639,27 @@ "nice-napi": "^1.0.2" } }, + "node_modules/pixelmatch": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz", + "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==", + "dev": true, + "dependencies": { + "pngjs": "^6.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pixelmatch/node_modules/pngjs": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", + "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "dev": true, + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -32827,6 +32795,15 @@ "node": ">=4" } }, + "node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/portfinder": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", @@ -35021,10 +34998,9 @@ "license": "Apache-2.0" }, "node_modules/rxjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.0.tgz", - "integrity": "sha512-fuCKAfFawVYX0pyFlETtYnXI+5iiY9Dftgk+VdgeOq+Qyi9ZDWckHZRDaXRt5WCNbbLkmAheoSGDiceyCIKNZA==", - "license": "Apache-2.0", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dependencies": { "tslib": "^2.1.0" } @@ -40481,8 +40457,8 @@ "@angular/common": ">=16.0.0", "@angular/core": ">=16.0.0", "@ng-web-apis/common": "^4.6.5", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "tslib": "^2.7.0" } @@ -40499,10 +40475,10 @@ "@maskito/core": "^3.0.3", "@maskito/kit": "^3.0.3", "@ng-web-apis/common": "^4.6.5", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", - "@taiga-ui/i18n": "^4.8.1", - "@taiga-ui/kit": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", + "@taiga-ui/i18n": "^4.9.0", + "@taiga-ui/kit": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "rxjs": ">=7.0.0", "tslib": "^2.7.0" @@ -40522,10 +40498,10 @@ "@angular/forms": ">=16.0.0", "@angular/router": ">=16.0.0", "@ng-web-apis/common": "^4.6.5", - "@taiga-ui/addon-mobile": "^4.8.1", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", - "@taiga-ui/kit": "^4.8.1", + "@taiga-ui/addon-mobile": "^4.9.0", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", + "@taiga-ui/kit": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "markdown-it": ">=14.1.0", "ngx-highlightjs": ">=10.0.0", @@ -40541,9 +40517,9 @@ "@angular/common": ">=16.0.0", "@angular/core": ">=16.0.0", "@ng-web-apis/common": "^4.6.5", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", - "@taiga-ui/kit": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", + "@taiga-ui/kit": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "rxjs": ">=7.0.0", "tslib": "^2.7.0" @@ -40557,10 +40533,10 @@ "@angular/common": ">=16.0.0", "@angular/core": ">=16.0.0", "@ng-web-apis/intersection-observer": "^4.6.5", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", - "@taiga-ui/i18n": "^4.8.1", - "@taiga-ui/kit": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", + "@taiga-ui/i18n": "^4.9.0", + "@taiga-ui/kit": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "rxjs": ">=7.0.0", "tslib": "^2.7.0" @@ -40613,9 +40589,9 @@ "@angular/router": ">=16.0.0", "@ng-web-apis/common": "^4.6.5", "@ng-web-apis/mutation-observer": "^4.6.5", - "@taiga-ui/cdk": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", "@taiga-ui/event-plugins": "^4.2.4", - "@taiga-ui/i18n": "^4.8.1", + "@taiga-ui/i18n": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "rxjs": ">=7.0.0", "tslib": "^2.7.0" @@ -40640,7 +40616,7 @@ "@stackblitz/sdk": "1.11.0", "@taiga-ui/dompurify": "4.1.7", "date-fns": "4.1.0", - "rxjs": "7.5.0" + "rxjs": "7.8.1" }, "devDependencies": { "@nguniversal/builders": "16.2.0", @@ -40653,7 +40629,8 @@ "name": "@taiga-ui/demo-cypress", "devDependencies": { "@nx/cypress": "19.8.2", - "cypress": "13.15.0" + "cypress": "13.15.0", + "cypress-image-diff-js": "2.2.1" } }, "projects/demo-playwright": { @@ -40669,10 +40646,10 @@ "peerDependencies": { "@angular/common": ">=16.0.0", "@angular/core": ">=16.0.0", - "@taiga-ui/addon-commerce": "^4.8.1", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", - "@taiga-ui/kit": "^4.8.1", + "@taiga-ui/addon-commerce": "^4.9.0", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", + "@taiga-ui/kit": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "rxjs": ">=7.0.0", "tslib": "^2.7.0" @@ -40730,9 +40707,9 @@ "@ng-web-apis/intersection-observer": "^4.6.5", "@ng-web-apis/mutation-observer": "^4.6.5", "@ng-web-apis/resize-observer": "^4.6.5", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", - "@taiga-ui/i18n": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", + "@taiga-ui/i18n": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "rxjs": ">=7.0.0", "tslib": "^2.7.0" @@ -40745,9 +40722,9 @@ "peerDependencies": { "@angular/common": ">=16.0.0", "@angular/core": ">=16.0.0", - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", - "@taiga-ui/kit": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", + "@taiga-ui/kit": "^4.9.0", "@taiga-ui/polymorpheus": "^4.7.4", "rxjs": ">=7.0.0", "tslib": "^2.7.0" @@ -40766,8 +40743,8 @@ "name": "@taiga-ui/styles", "version": "4.9.0", "peerDependencies": { - "@taiga-ui/cdk": "^4.8.1", - "@taiga-ui/core": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", + "@taiga-ui/core": "^4.9.0", "tslib": "^2.7.0" } }, @@ -40779,7 +40756,7 @@ "@taiga-ui/cdk": "^4.9.0" }, "peerDependencies": { - "@taiga-ui/cdk": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", "tslib": "^2.7.0" } }, @@ -40793,7 +40770,7 @@ "ts-jest": "29.2.5" }, "peerDependencies": { - "@taiga-ui/cdk": "^4.8.1", + "@taiga-ui/cdk": "^4.9.0", "tslib": "^2.7.0" } } diff --git a/package.json b/package.json index 40a9234fbe68..487ee708ba11 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "ng-packagr": "16.2.3", "ngx-highlightjs": "10.0.0", "nx": "19.8.2", - "rxjs": "7.5.0", + "rxjs": "7.8.1", "standard-version": "9.5.0", "ts-mockito": "2.6.1", "ts-node": "10.9.2", diff --git a/projects/demo-cypress/cypress-image-diff.config.js b/projects/demo-cypress/cypress-image-diff.config.js new file mode 100644 index 000000000000..d7f30e063186 --- /dev/null +++ b/projects/demo-cypress/cypress-image-diff.config.js @@ -0,0 +1,9 @@ +module.exports = { + ROOT_DIR: 'tests-results', + SCREENSHOTS_DIR: 'snapshots', + REPORT_DIR: '.', + JSON_REPORT: { + FILENAME: 'report-summary', + OVERWRITE: true, + }, +}; diff --git a/projects/demo-cypress/cypress.config.ts b/projects/demo-cypress/cypress.config.ts index 40cca3fc756b..30cf708387f4 100644 --- a/projects/demo-cypress/cypress.config.ts +++ b/projects/demo-cypress/cypress.config.ts @@ -1,5 +1,6 @@ import {nxComponentTestingPreset} from '@nx/angular/plugins/component-testing'; import {defineConfig} from 'cypress'; +import getCompareSnapshotsPlugin from 'cypress-image-diff-js/plugin'; const preset = nxComponentTestingPreset(__filename); @@ -44,5 +45,8 @@ export default defineConfig({ indexHtmlFile: 'src/support/component-index.html', specPattern: 'src/tests/**/*.cy.ts', experimentalSingleTabRunMode: true, + setupNodeEvents(on, config) { + return getCompareSnapshotsPlugin(on, config); + }, }, }); diff --git a/projects/demo-cypress/package.json b/projects/demo-cypress/package.json index d2c6260d72b5..7663bbc06fa3 100644 --- a/projects/demo-cypress/package.json +++ b/projects/demo-cypress/package.json @@ -3,6 +3,7 @@ "private": true, "devDependencies": { "@nx/cypress": "19.8.2", - "cypress": "13.15.0" + "cypress": "13.15.0", + "cypress-image-diff-js": "2.2.1" } } diff --git a/projects/demo-cypress/src/support/component-index.html b/projects/demo-cypress/src/support/component-index.html index 39ca75702d5f..6bbf3e4c8754 100644 --- a/projects/demo-cypress/src/support/component-index.html +++ b/projects/demo-cypress/src/support/component-index.html @@ -13,6 +13,9 @@