diff --git a/.gitignore b/.gitignore index 47be93aa..94e94e56 100644 --- a/.gitignore +++ b/.gitignore @@ -94,6 +94,7 @@ site-template theme/.env ### BackstopJS Files ### +theme/test_data/bitmaps_reference/ theme/test_data/bitmaps_test/ theme/test_data/html_report/ diff --git a/theme/env_template b/theme/env_template index 7341dd10..51d0b666 100644 --- a/theme/env_template +++ b/theme/env_template @@ -6,3 +6,13 @@ AEM_SITE= # AEM proxy port AEM_PROXY_PORT=7000 + +# AEM username +AEM_USERNAME=admin + + +# AEM password +AEM_PASSWORD=admin + +# (OPTIONAL) Path to google drive regression test images +GOOGLE_DRIVE_TEST_IMAGES_PATH=G:/.shortcut-targets-by-id/{id of shared drive}/regresstiontestimages \ No newline at end of file diff --git a/theme/live.test.config.js b/theme/live.test.config.js index 67f8ef30..284123a0 100644 --- a/theme/live.test.config.js +++ b/theme/live.test.config.js @@ -1,61 +1,58 @@ const config = require("./test.config"); +const baseURL = `http://localhost:4502/content/${config.aemSite}/`; +const queryParams = "?wcmmode=disabled"; + +// add pages you want tested here: +const pagesToTest = ["en/home.html", "guide.html"]; + +// add advanced tests here: +const scenarios = [ + // { + // label: "", + // url: ``, + // cookiePath: "", + // referenceUrl: "", + // readyEvent: "", + // readySelector: "", + // delay: 0, + // hideSelectors: [], + // removeSelectors: [], + // hoverSelector: "", + // clickSelector: "", + // postInteractionWait: 0, + // selectors: [], + // selectorExpansion: true, + // expect: 0, + // }, + { + label: "mobile-menu", + login: config.aemLogin, + url: baseURL + "en/home.html", + viewports: [ + { + label: "phone", + width: 320, + height: 480, + }, + ], + clickSelector: "#mobile-header-button", + }, +]; + +pagesToTest.forEach((url) => { + const name = url.slice(url.lastIndexOf("/") + 1, url.indexOf(".html")); + + scenarios.push({ + label: name, + login: config.aemLogin, + url: baseURL + url + queryParams, + }); +}); + module.exports = { ...config, - scenarios: [ - // { - // label: "", - // url: ``, - // cookiePath: "", - // referenceUrl: "", - // readyEvent: "", - // readySelector: "", - // delay: 0, - // hideSelectors: [], - // removeSelectors: [], - // hoverSelector: "", - // clickSelector: "", - // postInteractionWait: 0, - // selectors: [], - // selectorExpansion: true, - // expect: 0, - // }, - { - label: "Home", - login: config.aemLogin, - url: `http://localhost:${config.aemPort + 1}/content/${ - config.aemSite - }/en/home.html`, - cookiePath: "", - referenceUrl: "", - readyEvent: "", - readySelector: "", - delay: 0, - hideSelectors: [], - removeSelectors: [], - hoverSelector: "", - clickSelector: "", - postInteractionWait: 0, - selectors: [], - selectorExpansion: true, - expect: 0, - }, - { - label: "mobile-menu", - login: config.aemLogin, - url: `http://localhost:${config.aemPort + 1}/content/${ - config.aemSite - }/en/home.html`, - viewports: [ - { - label: "phone", - width: 320, - height: 480, - }, - ], - clickSelector: "#mobile-header-button", - }, - ], + scenarios, // set to one, so browser sync doesn't mess with click/inputs/scrolling during screenshots asyncCaptureLimit: 1, }; diff --git a/theme/local.test.config.js b/theme/local.test.config.js index 252dfdb5..bd5473fa 100644 --- a/theme/local.test.config.js +++ b/theme/local.test.config.js @@ -1,17 +1,55 @@ const config = require("./test.config"); -const url = - "http://localhost:4502/content/aem-site-template-tailwind/en/home.html"; +const baseURL = `http://localhost:4502/content/${config.aemSite}/`; +const queryParams = "?wcmmode=disabled"; + +// add pages you want tested here: +const pagesToTest = [ + "en/home.html", + "guide.html", + "guide/manage.html", + "guide/manage/assets.html", + "guide/manage/site-elements.html", + "guide/manage/authoring.html", + "guide/manage/create-a-page.html", + "guide/manage/publish.html", + "guide/customize.html", + "en/article.html", + "en/article/donec-tristique-efficitur.html", + "en/article/fusce-at-efficitur-mi.html", + "en/article/morbi-dapibus-libero-velit.html", + "en/article/duis-bibendum-vitae.html", + "en/contact-us.html", +]; + +// add advanced tests here: +const scenarios = [ + { + label: "mobile-menu", + login: config.aemLogin, + url: baseURL + "en/home.html", + viewports: [ + { + label: "phone", + width: 320, + height: 480, + }, + ], + clickSelector: "#mobile-header-button", + }, +]; + +pagesToTest.forEach((url) => { + const name = url.slice(url.lastIndexOf("/") + 1, url.indexOf(".html")); + + scenarios.push({ + label: name, + login: config.aemLogin, + url: baseURL + url + queryParams, + }); +}); module.exports = { ...config, - scenarios: [ - { - label: "Home", - login: config.aemLogin, - // cookiePath: "", - url: url, - // referenceUrl: "", - }, - ], + scenarios, }; diff --git a/theme/package-lock.json b/theme/package-lock.json index 41d19b21..2fedc2b3 100644 --- a/theme/package-lock.json +++ b/theme/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT License, Copyright 2022 headwire.com, Inc", "dependencies": { "backstopjs": "^6.0.4", + "fs-extra": "^10.0.1", "inquirer": "^8.2.0" }, "devDependencies": { @@ -4159,6 +4160,26 @@ "ms": "2.0.0" } }, + "node_modules/browser-sync/node_modules/fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/browser-sync/node_modules/jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/browser-sync/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4171,6 +4192,15 @@ "node": ">=8" } }, + "node_modules/browser-sync/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/browser-sync/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -7189,14 +7219,16 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/fs.realpath": { @@ -8971,10 +9003,12 @@ } }, "node_modules/jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -16625,12 +16659,11 @@ "dev": true }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "engines": { - "node": ">= 4.0.0" + "node": ">= 10.0.0" } }, "node_modules/unpipe": { @@ -20040,6 +20073,26 @@ "ms": "2.0.0" } }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -20049,6 +20102,12 @@ "ansi-regex": "^5.0.1" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -22417,14 +22476,13 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, "fs.realpath": { @@ -23741,12 +23799,12 @@ } }, "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, "jsprim": { @@ -29459,10 +29517,9 @@ "dev": true }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" }, "unpipe": { "version": "1.0.0", diff --git a/theme/package.json b/theme/package.json index 57f1acab..5bb9c872 100644 --- a/theme/package.json +++ b/theme/package.json @@ -18,10 +18,10 @@ "watch:color-scheme": "parcel watch src/color-scheme.ts", "watch:theme": "parcel watch src/theme.ts", "test-live-config": "backstop test --config=live.test.config.js", - "test:local": "backstop test --config=local.test.config.js", - "test:live": "run-p live test-live-config", - "test:update-local": "backstop approve --config=local.test.config.js", - "test:update-live": "backstop approve --config=live.test.config.js" + "test:local": "node ./test_data/loadImagesFromDrive.js && backstop test --config=local.test.config.js", + "test:live": "node ./test_data/loadImagesFromDrive.js && run-p live test-live-config", + "test:update-local": "backstop approve --config=local.test.config.js && node ./test_data/uploadImagesToDrive.js", + "test:update-live": "backstop approve --config=live.test.config.js && node ./test_data/uploadImagesToDrive.js" }, "devDependencies": { "@adobe/aem-site-theme-builder": "5.2.1", @@ -64,6 +64,7 @@ }, "dependencies": { "backstopjs": "^6.0.4", + "fs-extra": "^10.0.1", "inquirer": "^8.2.0" } } diff --git a/theme/test.config.js b/theme/test.config.js index dac68caf..fc1efc9d 100644 --- a/theme/test.config.js +++ b/theme/test.config.js @@ -3,6 +3,7 @@ const { aemSite, aemPort, login, + googleDrivePath, } = require("./test_data/get-live-server-details"); module.exports = { @@ -10,6 +11,7 @@ module.exports = { aemLogin: login, aemSite, aemPort, + googleDrivePath, viewports: [ { label: "phone", diff --git a/theme/test_data/bitmaps_reference/backstop_default_Home_0_document_0_phone.png b/theme/test_data/bitmaps_reference/backstop_default_Home_0_document_0_phone.png deleted file mode 100644 index 727c5f79..00000000 Binary files a/theme/test_data/bitmaps_reference/backstop_default_Home_0_document_0_phone.png and /dev/null differ diff --git a/theme/test_data/bitmaps_reference/backstop_default_Home_0_document_1_desktop.png b/theme/test_data/bitmaps_reference/backstop_default_Home_0_document_1_desktop.png deleted file mode 100644 index a30ad6b3..00000000 Binary files a/theme/test_data/bitmaps_reference/backstop_default_Home_0_document_1_desktop.png and /dev/null differ diff --git a/theme/test_data/bitmaps_reference/backstop_default_mobile-menu_0_document_0_phone.png b/theme/test_data/bitmaps_reference/backstop_default_mobile-menu_0_document_0_phone.png deleted file mode 100644 index 834e8fde..00000000 Binary files a/theme/test_data/bitmaps_reference/backstop_default_mobile-menu_0_document_0_phone.png and /dev/null differ diff --git a/theme/test_data/bitmaps_reference/test_default_Home_0_document_0_phone.png b/theme/test_data/bitmaps_reference/test_default_Home_0_document_0_phone.png deleted file mode 100644 index 727c5f79..00000000 Binary files a/theme/test_data/bitmaps_reference/test_default_Home_0_document_0_phone.png and /dev/null differ diff --git a/theme/test_data/bitmaps_reference/test_default_Home_0_document_1_desktop.png b/theme/test_data/bitmaps_reference/test_default_Home_0_document_1_desktop.png deleted file mode 100644 index a30ad6b3..00000000 Binary files a/theme/test_data/bitmaps_reference/test_default_Home_0_document_1_desktop.png and /dev/null differ diff --git a/theme/test_data/bitmaps_reference/test_default_mobile-menu_0_document_0_phone.png b/theme/test_data/bitmaps_reference/test_default_mobile-menu_0_document_0_phone.png deleted file mode 100644 index 834e8fde..00000000 Binary files a/theme/test_data/bitmaps_reference/test_default_mobile-menu_0_document_0_phone.png and /dev/null differ diff --git a/theme/test_data/engine_scripts/playwright/loginAndLazyLoadScroll.js b/theme/test_data/engine_scripts/playwright/loginAndLazyLoadScroll.js index 3e272ccf..969f2935 100644 --- a/theme/test_data/engine_scripts/playwright/loginAndLazyLoadScroll.js +++ b/theme/test_data/engine_scripts/playwright/loginAndLazyLoadScroll.js @@ -12,15 +12,30 @@ module.exports = async (page, scenario) => { await page.waitForLoadState(); // this is needed because images are lazily loaded - await page.evaluate(() => { - window.scrollTo({ - left: 0, - top: document.body.scrollHeight, - behavior: "smooth", + await page.evaluate(async () => { + await new Promise((resolve, reject) => { + const scrollCheck = setInterval(() => { + if ( + window.scrollY >= + Math.floor(document.body.scrollHeight - window.innerHeight - 1) + ) { + clearInterval(scrollCheck); + resolve(); + } + window.scrollTo({ + left: 0, + top: document.body.scrollHeight, + behavior: "smooth", + }); + }, 500); }); }); - await page.waitForSelector(".cmp-image__image--is-loading", { - state: "detached", + + await page.waitForFunction(() => { + return Array.from(document.images).every((i) => { + console.log(i.complete); + return i.complete; + }); }); // waiting for browser sync notification to go away diff --git a/theme/test_data/get-live-server-details.js b/theme/test_data/get-live-server-details.js index e23ce9b1..87a751ee 100644 --- a/theme/test_data/get-live-server-details.js +++ b/theme/test_data/get-live-server-details.js @@ -12,6 +12,16 @@ const username = lines.findIndex((string) => const password = lines.findIndex((string) => string.startsWith("AEM_PASSWORD=") ); +const googleDrive = lines.findIndex((string) => + string.startsWith("GOOGLE_DRIVE_TEST_IMAGES_PATH=") +); + +const googleDrivePath = () => { + if (googleDrive === -1) { + return null; + } + return lines[googleDrive].split("=")[1]; +}; module.exports = { aemSite: lines[siteIndex].split("=")[1], @@ -20,4 +30,5 @@ module.exports = { aemUsername: lines[username].split("=")[1], aemPassword: lines[password].split("=")[1], }, + googleDrivePath: googleDrivePath(), }; diff --git a/theme/test_data/loadImagesFromDrive.js b/theme/test_data/loadImagesFromDrive.js new file mode 100644 index 00000000..4f9f4052 --- /dev/null +++ b/theme/test_data/loadImagesFromDrive.js @@ -0,0 +1,11 @@ +const fse = require("fs-extra"); +const { googleDrivePath, paths } = require("../test.config"); + +if (googleDrivePath) { + try { + fse.copySync(googleDrivePath, paths.bitmaps_reference); + console.log("✔ Successfully copied refrence Images from google drive"); + } catch (error) { + console.log("❌ error copying images from google drive: ", error); + } +} diff --git a/theme/test_data/uploadImagesToDrive.js b/theme/test_data/uploadImagesToDrive.js new file mode 100644 index 00000000..e2b3440a --- /dev/null +++ b/theme/test_data/uploadImagesToDrive.js @@ -0,0 +1,13 @@ +const fse = require("fs-extra"); +const { googleDrivePath, paths } = require("../test.config"); + +if (googleDrivePath) { + try { + fse.copySync(paths.bitmaps_reference, googleDrivePath); + console.log( + "✔ Successfully copied new refrance images to google drive folder!" + ); + } catch (error) { + console.log("❌ error copying images to google drive: ", error); + } +}