diff --git a/.github/workflows/submitty_ci.yml b/.github/workflows/submitty_ci.yml index 0bc60e944e2..9b7cdc527b5 100644 --- a/.github/workflows/submitty_ci.yml +++ b/.github/workflows/submitty_ci.yml @@ -493,6 +493,7 @@ jobs: with: name: cypress-screenshots path: ${{env.SUBMITTY_REPOSITORY}}/site/cypress/screenshots + - uses: actions/upload-artifact@v4 if: failure() with: @@ -555,12 +556,15 @@ jobs: - name: Check for site errors working-directory: ${{ env.SUBMITTY_REPOSITORY }} run: sudo bash tests/test_site_error_log.sh - + - uses: actions/upload-artifact@v4 if: failure() with: - name: cypress-screenshots - path: ${{env.SUBMITTY_REPOSITORY}}/site/cypress/screenshots + name: cypress-image-ss + path: | + ${{env.SUBMITTY_REPOSITORY}}/site/cypress/screenshots + ${{env.SUBMITTY_REPOSITORY}}/site/cypress-image-diff-screenshots + - uses: actions/upload-artifact@v4 if: failure() with: diff --git a/.gitignore b/.gitignore index dc688800ab7..2b1771023de 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,9 @@ coverage.xml /site/public/vue/ /site/report/ /site/incremental_build/ +/site/cypress-image-diff-screenshots/comparison/ +/site/cypress-image-diff-screenshots/diff/ +/site/cypress-image-diff-html-report db_update.php .setup/data/random_users.txt diff --git a/site/app/templates/autograding/AutoChecks.twig b/site/app/templates/autograding/AutoChecks.twig index 1c4d51c10c5..3971e1e9e1b 100644 --- a/site/app/templates/autograding/AutoChecks.twig +++ b/site/app/templates/autograding/AutoChecks.twig @@ -37,7 +37,7 @@ {% endif %} -
+
{% if not check.actual is defined and check.description is defined and check.messages is defined%}

{{ check.description }}

diff --git a/site/app/templates/autograding/AutoResults.twig b/site/app/templates/autograding/AutoResults.twig index d1987f28e1f..0cac941c4e9 100644 --- a/site/app/templates/autograding/AutoResults.twig +++ b/site/app/templates/autograding/AutoResults.twig @@ -98,7 +98,7 @@ {% endif %} {% endif %} > - + Expand All Test Cases diff --git a/site/app/templates/forum/ShowForumThreads.twig b/site/app/templates/forum/ShowForumThreads.twig index 3251779a56b..0ed28a1d668 100644 --- a/site/app/templates/forum/ShowForumThreads.twig +++ b/site/app/templates/forum/ShowForumThreads.twig @@ -104,7 +104,7 @@ } }); -
+
{% include "forum/GeneratePostList.twig" with { "userGroup" : generate_post_content.userGroup, diff --git a/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-bottom.png b/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-bottom.png new file mode 100644 index 00000000000..57a55198c6e Binary files /dev/null and b/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-bottom.png differ diff --git a/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-center.png b/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-center.png new file mode 100644 index 00000000000..2995d8fac69 Binary files /dev/null and b/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-center.png differ diff --git a/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-top.png b/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-top.png new file mode 100644 index 00000000000..fb1c2a2c463 Binary files /dev/null and b/site/cypress-image-diff-screenshots/baseline/forums.spec-forum-threads-top.png differ diff --git a/site/cypress/e2e/Cypress-Feature/forums.spec.js b/site/cypress/e2e/Cypress-Feature/forums.spec.js index 8fab7ec5776..04c04c543cd 100644 --- a/site/cypress/e2e/Cypress-Feature/forums.spec.js +++ b/site/cypress/e2e/Cypress-Feature/forums.spec.js @@ -63,6 +63,26 @@ const removeThread = (title) => { cy.get('[data-testid="thread-list-item"]').contains(title).should('not.exist'); }; +describe('Visuals', () => { + it('should compare screenshot of the entire page', () => { + cy.viewport(1000, 920); + cy.login('instructor'); + cy.visit(['sample', 'forum', 'threads', '9']); + cy.get('[data-testid="markdown-post-list"]').scrollTo('top'); + cy.get('[data-testid="markdown-post-list"]').compareSnapshot('forum-threads-top', 0.02, { + capture: 'viewport', + }); + cy.get('[data-testid="markdown-post-list"]').scrollTo('center'); + cy.get('[data-testid="markdown-post-list"]').compareSnapshot('forum-threads-center', 0.02, { + capture: 'viewport', + }); + cy.get('[data-testid="markdown-post-list"]').scrollTo('bottom'); + cy.get('[data-testid="markdown-post-list"]').compareSnapshot('forum-threads-bottom', 0.02, { + capture: 'viewport', + }); + }); +}); + const uploadAttachmentAndDelete = (title, attachment) => { cy.get('[data-testid="thread-list-item"]').contains(title).click(); cy.get('[data-testid="create-post-head"]').should('contain', title); diff --git a/site/cypress/plugins/index.js b/site/cypress/plugins/index.js index dda9b09d83b..6554b9318f2 100644 --- a/site/cypress/plugins/index.js +++ b/site/cypress/plugins/index.js @@ -12,10 +12,14 @@ // This function is called when a project is opened or re-opened (e.g. due to // the project's config changing) +// eslint-disable-next-line no-undef +const getCompareSnapshotsPlugin = require('cypress-image-diff-js/plugin'); + /** * @type {Cypress.PluginConfig} */ -export default function (/* on, config */) { +export default function (on, config) { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config + return getCompareSnapshotsPlugin(on, config); } diff --git a/site/cypress/support/e2e.js b/site/cypress/support/e2e.js index d83fd4e87ba..d82762588d4 100644 --- a/site/cypress/support/e2e.js +++ b/site/cypress/support/e2e.js @@ -27,3 +27,7 @@ afterEach(() => { cy.logout(true, checkLogout); }); }); + +// eslint-disable-next-line no-undef +const compareSnapshotCommand = require('cypress-image-diff-js/command'); +compareSnapshotCommand(); diff --git a/site/package-lock.json b/site/package-lock.json index f8703820a5c..4361b111ad7 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -59,6 +59,7 @@ "cypress": "^13.13.0", "cypress-browser-permissions": "^1.1.0", "cypress-file-upload": "^5.0.8", + "cypress-image-diff-js": "^2.1.4", "esbuild": "^0.21.1", "eslint": "^8.57.0", "eslint-plugin-cypress": "^3.3.0", @@ -2332,6 +2333,20 @@ "w3c-keyname": "^2.2.4" } }, + "node_modules/@codemirror/view/node_modules/@codemirror/state": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz", + "integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A==" + }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@csstools/css-parser-algorithms": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", @@ -4619,6 +4634,12 @@ } ] }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.10", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", @@ -5726,6 +5747,38 @@ "cypress": ">3.0.0" } }, + "node_modules/cypress-image-diff-js": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cypress-image-diff-js/-/cypress-image-diff-js-2.1.4.tgz", + "integrity": "sha512-bhsCt1+cp6kIcECtIrS2o67qWgqOlTfam3hMGoGPbOKPTvFDg0/G9wGwPqCPDRuJ0B4LgsQgKpPi4UXoC5SKyg==", + "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.2", + "resolved": "https://registry.npmjs.org/cypress-recurse/-/cypress-recurse-1.35.2.tgz", + "integrity": "sha512-G6HfxP90xa7phw8oeOX4uabxcI9gE1ktkKHShcA3nCByrkMLs56+GIJVn0A+ws1tI0PGRKBz6+V9DHS5WnZX4A==", + "dev": true, + "dependencies": { + "humanize-duration": "^3.27.3" + } + }, "node_modules/cypress/node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", @@ -7563,6 +7616,27 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -7723,6 +7797,12 @@ "node": ">=8.12.0" } }, + "node_modules/humanize-duration": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.31.0.tgz", + "integrity": "sha512-fRrehgBG26NNZysRlTq1S+HPtDpp3u+Jzdc/d5A4cEzOD86YLAkDaJyJg8krSdCi7CJ+s7ht3fwRj8Dl+Btd0w==", + "dev": true + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -8034,9 +8114,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -10083,8 +10163,7 @@ }, "node_modules/neo-async": { "version": "2.6.2", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "peer": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/node-fetch": { "version": "2.6.12", @@ -10413,6 +10492,27 @@ "node": ">= 6" } }, + "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", @@ -10430,6 +10530,15 @@ "resolved": "https://registry.npmjs.org/plotly.js-dist/-/plotly.js-dist-2.25.2.tgz", "integrity": "sha512-C2hsTfqAZGRJYJBTZx2+eN6BKZPZC4nvy0ejFU1VW88IBO85xuZYDRUnILMgX0CQ3i26PVfYaR2BWO8Af7KqPQ==" }, + "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/popper.js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", @@ -12072,6 +12181,18 @@ "version": "1.2.0", "integrity": "sha512-dELuLBVa2jvWdU/CHTKi2L/POYaRupv942k+vRsFXsM17acXesQGAiGCio82RW7fvcr7bkuD/Zj8XpUh6aPC2A==" }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -12469,6 +12590,12 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, "node_modules/worker-loader": { "version": "3.0.8", "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", @@ -14358,6 +14485,12 @@ "w3c-keyname": "^2.2.4" } }, + "@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "dev": true + }, "@csstools/css-parser-algorithms": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", @@ -16007,6 +16140,12 @@ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", @@ -16837,6 +16976,32 @@ "dev": true, "requires": {} }, + "cypress-image-diff-js": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cypress-image-diff-js/-/cypress-image-diff-js-2.1.4.tgz", + "integrity": "sha512-bhsCt1+cp6kIcECtIrS2o67qWgqOlTfam3hMGoGPbOKPTvFDg0/G9wGwPqCPDRuJ0B4LgsQgKpPi4UXoC5SKyg==", + "dev": true, + "requires": { + "@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" + } + }, + "cypress-recurse": { + "version": "1.35.2", + "resolved": "https://registry.npmjs.org/cypress-recurse/-/cypress-recurse-1.35.2.tgz", + "integrity": "sha512-G6HfxP90xa7phw8oeOX4uabxcI9gE1ktkKHShcA3nCByrkMLs56+GIJVn0A+ws1tI0PGRKBz6+V9DHS5WnZX4A==", + "dev": true, + "requires": { + "humanize-duration": "^3.27.3" + } + }, "cytoscape": { "version": "3.28.1", "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.28.1.tgz", @@ -18161,6 +18326,19 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -18273,6 +18451,12 @@ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true }, + "humanize-duration": { + "version": "3.31.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.31.0.tgz", + "integrity": "sha512-fRrehgBG26NNZysRlTq1S+HPtDpp3u+Jzdc/d5A4cEzOD86YLAkDaJyJg8krSdCi7CJ+s7ht3fwRj8Dl+Btd0w==", + "dev": true + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -18483,9 +18667,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -19930,8 +20114,7 @@ }, "neo-async": { "version": "2.6.2", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "peer": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node-fetch": { "version": "2.6.12", @@ -20174,6 +20357,23 @@ "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", "dev": true }, + "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, + "requires": { + "pngjs": "^6.0.0" + }, + "dependencies": { + "pngjs": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", + "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "dev": true + } + } + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -20188,6 +20388,12 @@ "resolved": "https://registry.npmjs.org/plotly.js-dist/-/plotly.js-dist-2.25.2.tgz", "integrity": "sha512-C2hsTfqAZGRJYJBTZx2+eN6BKZPZC4nvy0ejFU1VW88IBO85xuZYDRUnILMgX0CQ3i26PVfYaR2BWO8Af7KqPQ==" }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "dev": true + }, "popper.js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", @@ -21345,6 +21551,12 @@ "version": "1.2.0", "integrity": "sha512-dELuLBVa2jvWdU/CHTKi2L/POYaRupv942k+vRsFXsM17acXesQGAiGCio82RW7fvcr7bkuD/Zj8XpUh6aPC2A==" }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -21635,6 +21847,12 @@ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, "worker-loader": { "version": "3.0.8", "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", diff --git a/site/package.json b/site/package.json index 568a14f9fde..8e503cb9840 100644 --- a/site/package.json +++ b/site/package.json @@ -65,6 +65,7 @@ "cypress": "^13.13.0", "cypress-browser-permissions": "^1.1.0", "cypress-file-upload": "^5.0.8", + "cypress-image-diff-js": "^2.1.4", "esbuild": "^0.21.1", "eslint": "^8.57.0", "eslint-plugin-cypress": "^3.3.0",