diff --git a/.gitignore b/.gitignore index a03b29c..407dd4e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ .vscode .docker /docker-compose.yml +cypress.config.mjs +tests/screenshots # NPM node_modules diff --git a/README.md b/README.md index 120aa1a..902fe99 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,13 @@ [![version][version-badge]][package] -This is a support package that helps in writing end-to-end tests for the [Joomla CMS](https://joomla.org) and its extensions with the frontend testing tool [Cypress](/https://www.cypress.io/). +This is a support package that helps in writing end-to-end tests for the [Joomla CMS](https://joomla.org) and its extensions with the frontend testing tool [Cypress](https://www.cypress.io/). The Joomla default branch and all active development [branches](https://github.com/joomla/joomla-cms/branches) are supported. +Instructions for testing the package are provided and documented in the +[tests](tests) sub-folder. +The test suite also shows the use of the Cypress custom commands. + ## Installation `joomla-cypress` is distributed with [npm](https://npmjs.com/) and works with the latest version of Cypress. diff --git a/images/test-run.png b/images/test-run.png new file mode 100644 index 0000000..4dff121 Binary files /dev/null and b/images/test-run.png differ diff --git a/images/test-user.png b/images/test-user.png new file mode 100644 index 0000000..6c534a8 Binary files /dev/null and b/images/test-user.png differ diff --git a/package-lock.json b/package-lock.json index da60d22..b5afb83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.2.0", "license": "GPL-2.0+", "dependencies": { - "cypress": "^13.15.0", + "cypress": "^13.16.0", "cypress-file-upload": "^5.0.8" } }, @@ -24,9 +24,9 @@ } }, "node_modules/@cypress/request": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.5.tgz", - "integrity": "sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.6.tgz", + "integrity": "sha512-fi0eVdCOtKu5Ed6+E8mYxUF6ZTFJDZvHogCBelM0xVXmrDEkyM22gRArQzq1YcHPm1V47Vf/iAD+WgVdUlJCGg==", "license": "Apache-2.0", "dependencies": { "aws-sign2": "~0.7.0", @@ -44,7 +44,7 @@ "performance-now": "^2.1.0", "qs": "6.13.0", "safe-buffer": "^5.1.2", - "tough-cookie": "^4.1.3", + "tough-cookie": "^5.0.0", "tunnel-agent": "^0.6.0", "uuid": "^8.3.2" }, @@ -331,16 +331,15 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -349,6 +348,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.0.tgz", + "integrity": "sha512-CCKAP2tkPau7D3GE8+V8R6sQubA9R5foIzGp+85EXCVSCivuxBNAWqcpn72PKYiIcqoViv/kcUDpaEIMBVi1lQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -393,9 +405,9 @@ } }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz", + "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==", "funding": [ { "type": "github", @@ -534,13 +546,13 @@ } }, "node_modules/cypress": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz", - "integrity": "sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==", + "version": "13.16.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.16.1.tgz", + "integrity": "sha512-17FtCaz0cx7ssWYKXzGB0Vub8xHwpVPr+iPt2fHhLMDhVAPVrplD+rTQsZUsfb19LVBn5iwkEUFjQ1yVVJXsLA==", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@cypress/request": "^3.0.4", + "@cypress/request": "^3.0.6", "@cypress/xvfb": "^1.2.4", "@types/sinonjs__fake-timers": "8.1.1", "@types/sizzle": "^2.3.2", @@ -551,6 +563,7 @@ "cachedir": "^2.3.0", "chalk": "^4.1.0", "check-more-types": "^2.24.0", + "ci-info": "^4.0.0", "cli-cursor": "^3.1.0", "cli-table3": "~0.6.1", "commander": "^6.2.1", @@ -565,7 +578,6 @@ "figures": "^3.2.0", "fs-extra": "^9.1.0", "getos": "^3.2.1", - "is-ci": "^3.0.1", "is-installed-globally": "~0.4.0", "lazy-ass": "^1.6.0", "listr2": "^3.8.3", @@ -580,6 +592,7 @@ "semver": "^7.5.3", "supports-color": "^8.1.1", "tmp": "~0.2.3", + "tree-kill": "1.2.2", "untildify": "^4.0.0", "yauzl": "^2.10.0" }, @@ -663,6 +676,20 @@ "node": ">=0.4.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -702,13 +729,10 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -879,16 +903,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -946,12 +973,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -984,22 +1011,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1081,18 +1096,6 @@ "node": ">=10" } }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -1391,9 +1394,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1504,12 +1507,6 @@ "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", "license": "MIT" }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "license": "MIT" - }, "node_modules/pump": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", @@ -1520,15 +1517,6 @@ "once": "^1.3.1" } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -1544,12 +1532,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "license": "MIT" - }, "node_modules/request-progress": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", @@ -1559,12 +1541,6 @@ "throttleit": "^1.0.0" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" - }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -1797,6 +1773,24 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, + "node_modules/tldts": { + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.66.tgz", + "integrity": "sha512-l3ciXsYFel/jSRfESbyKYud1nOw7WfhrBEF9I3UiarYk/qEaOOwu3qXNECHw4fHGHGTEOuhf/VdKgoDX5M/dhQ==", + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.66" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.66", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.66.tgz", + "integrity": "sha512-s07jJruSwndD2X8bVjwioPfqpIc1pDTzszPe9pL1Skbh4bjytL85KNQ3tolqLbCvpQHawIsGfFi9dgerWjqW4g==", + "license": "MIT" + }, "node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", @@ -1807,27 +1801,24 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" + "node": ">=16" } }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "bin": { + "tree-kill": "cli.js" } }, "node_modules/tslib": { @@ -1891,16 +1882,6 @@ "node": ">=8" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", diff --git a/package.json b/package.json index d73f320..97821e0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "description": "Helpers for using Cypress with Joomla for testing", "main": "src/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "clean": "rm -rf node_modules tests/cypress.config.mjs tests/screenshots", + "test": "npx cypress run --config-file tests/cypress.config.mjs", + "open": "npx cypress open --config-file tests/cypress.config.mjs", + "cypress:install": "cypress install" }, "repository": { "type": "git", @@ -24,7 +27,7 @@ "src" ], "dependencies": { - "cypress": "^13.15.0", + "cypress": "^13.16.0", "cypress-file-upload": "^5.0.8" } } diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..94fb7aa --- /dev/null +++ b/tests/README.md @@ -0,0 +1,160 @@ +# Cypress tests + +The testing of the NPM module `joomla-cypress` is implemented using Cypress as well. +Each Cypress custom command is executed at least once and the result is checked. + +## Running the tests + +Requirements: +* PHP (a Joomla-supported version) +* Composer +* NPM +* Cypress +* Web Server +* Joomla sources +* A database and PHP extensions for the database + +Ensure Firefox is installed system-wide (check with `npx cypress info`). + +For Joomla sources the following commands are sufficient: +``` +git clone https://github.com/joomla/joomla-cms --depth 1 +cd joomla-cms +composer install +npm ci +``` +No additional configuration for Joomla is necessary, as the parameters +are defined in the `joomla-cypress/tests/cypress.config.mjs` Cypress configuration file. +A Joomla installation is not required +if you start by running the entire test suite or the `tests/e2e/joomla.cy.js` test spec. + +> [!NOTE] +> The custom command `installJoomlaMultilingualSite` deletes the Joomla `installation` folder. +> You have to restore the `installation` folder after each test run, +> from saved copy or from GitHub and with recreating the `installation/template/css` folder: +> ``` +> git checkout installation +> npm ci +> ``` + +### Installation + +Install the JavaScript dependencies: +``` +git clone https://github.com/joomla-projects/joomla-cypress +cd joomla-cypress +npm ci +``` + +### Configuration + +Create the Cypress configuration file from the distribution template: +``` +cp tests/cypress.config.dist.mjs tests/cypress.config.mjs +``` + +Adapt the environment variables in the file `cypress.config.mjs`, +they should point to the site, user data and database environment. +Most configurations are the same as with Joomla System Tests `cypress.config.mjs` file. +Additional variables are +* `installationPath` contains the file system path to your Joomla installation + (used to delete the `configuration.php` file before installing Joomla) +* `instance` specifies the Joomla major and minor version number, e.g. `53` for Joomla 5.3. + +### Tests + +Running all tests headless: +``` +npm test +``` + +Running the test suite without the `installLanguage` and `installJoomlaMultilingualSite` tests, +if the language package is not yet available, on Windows PowerShell: +``` +$env:CYPRESS_SKIP_INSTALL_LANGUAGES=1 +npm test +``` + +Running only `user.cy.js` test spec file: +``` +npx cypress run --spec tests/e2e/user.cy.js --config-file tests/cypress.config.mjs +``` + +Running tests with local Cypress GUI: +``` +npm run open +``` + +## Running the tests using JBT + +JBT has integrated the testing of the NPM module `joomla-cypress`. +In the `installation/joomla-cypress` directory the latest main branch version is already installed. +Furthermore Joomla, databases, Cypress and sample module are already provided with JBT. +Restoring the `installation` folder, running `npm ci` and handing over the +sample module for installation are covered for you. +This is implemented in the scripts `tests`, `cypress` and `patch`. + +Patch `installation/joomla-cypress` e.g. with pull request `#37 Fixing installJoomlaMultilingualSite()`: +``` +scripts/patch installation joomla-cypress-37 +``` + +Running the test suite headless for Joomla 5.2: +``` +scripts/test 52 joomla-cypress +``` + + + +Running only `user.cy.js` test spec file and watching the progress with NoVNC: +``` +scripts/test 52 joomla-cypress tests/e2e/user.cy.js novnc +``` + + + +Running the test suite for Joomla 5.3 and 6.0 +without the `installLanguage` and `installJoomlaMultilingualSite` tests, +if the language package is not yet available, on Unix-based systems: + +``` +CYPRESS_SKIP_INSTALL_LANGUAGES=1 scripts/test 53 60 joomla-cypress +``` + +Running tests with local Cypress GUI, e.g. on macOS or Linux: +``` +scripts/cypress 52 joomla-cypress local +``` + +Running on Joomla 6.0 without the tests they install languages, +with the Cypress GUI, e.g. on Windows 11 WSL2 Ubuntu: +``` +CYPRESS_SKIP_INSTALL_LANGUAGES=1 scripts/cypress 60 joomla-cypress +``` + +# Troubleshooting + +1. Ensure that you have installed the version of `joomla-cypress` to be tested + and patched if necessary. +2. If one test step fails, the target Joomla installation may reach a state + causes subsequent tests to fail. Dependecies include + deleting Joomla `installation` folder, deleting the `configuration.php` file, + cancelling guided tours and disabling Joomla statistics. + In such cases open the target Joomla installation administration + to investigate or reinstall the target Joomla sources. +3. For failed tests you can inspect the screenshots in `tests/screenshots` folder or + run Cypresss GUI to observe the issue. +4. If the `installExtensionFromFolder()` test fails as the Joomla web server cannot + find the `mod_hello_world` package folder, set the folder with the enviroment + variable `CYPRESS_SERVER_UPLOAD_FOLDER`. For example on Unix-based systems: + ``` + export CYPRESS_SERVER_UPLOAD_FOLDER=/users/alice/joomla-cypress/tests/fixtures/mod_hello_world + ``` +5. For Joomla development versions that are not yet been released, + the tests `installLanguage` and `installJoomlaMultilingualSite` + fail with the error message `Unable to detect manifest file` + because the language packages are not yet available. + Exclude these tests by setting an environment variable on Unix-based systems: + ``` + export CYPRESS_SKIP_INSTALL_LANGUAGES=1 + ``` diff --git a/tests/cypress.config.dist.mjs b/tests/cypress.config.dist.mjs new file mode 100644 index 0000000..bfd6657 --- /dev/null +++ b/tests/cypress.config.dist.mjs @@ -0,0 +1,50 @@ +/** + * To run tests on your own installation, copy this file as 'cypress.config.mjs'. + * Then, review and adjust the configuration values to suit your setup. + */ +import { defineConfig } from 'cypress'; + +export default defineConfig({ + env: { + // As from Joomla System Tests + sitename: 'Joomla CMS Test', + name: 'jane doe', + email: 'admin@example.com', + username: 'ci-admin', + password: 'joomla-17082005', + db_type: 'MySQLi', + db_host: 'localhost', + db_port: '', + db_name: 'test_joomla', + db_user: 'joomla', + db_password: 'joomla', + db_prefix: 'jos_', + smtp_host: 'localhost', + smtp_port: '1025', + cmsPath: '.', + // Added for joomla-cypress tests + instance: 52, // Joomla major and minor version number + installationPath: 'C:/laragon/www/joomla52' // Joomla installation path + }, + e2e: { + baseUrl: 'http://localhost:9500', + supportFile: false, + // Just in case we are coming from a failed installation test, start with the Joomla installation + specPattern: ['tests/e2e/joomla.cy.js', 'tests/e2e/*.cy.js'], + screenshotsFolder: 'tests/screenshots', + fixturesFolder: 'tests/fixtures', + // Use Firefox as Joomla default and to prevent useless macOS Electron font warnings + // (Cypress 13.16.0 added 'defaultBrowser' option) + defaultBrowser: 'firefox', + setupNodeEvents(on, config) { + // For example, in a German environment, force the use of Firefox with British English. + on("before:browser:launch", (browser, launchOptions) => { + if (browser.family === "firefox") { + launchOptions.preferences["intl.accept_languages"] = "en-GB"; + } + return launchOptions; + }); + return config; + }, + }, +}); diff --git a/tests/e2e/common.cy.js b/tests/e2e/common.cy.js new file mode 100644 index 0000000..9237f6e --- /dev/null +++ b/tests/e2e/common.cy.js @@ -0,0 +1,76 @@ +/** + * common.cy.js – Cypress test suite for ../src/common.js custom commands + */ + +import { registerCommands } from '../support/registerCommands'; +import { config, caughtJavaScriptExceptions } from '../support/setup'; + +registerCommands(); + +beforeEach(() => { + caughtJavaScriptExceptions(); + cy.doAdministratorLogin(config.username, config.password, false); +}); + +describe("Test the Cypress custom commands from 'common.js' file", () => { + /* + * Stupid waits are inserted as a work-around for the error: + * 'Expected to find element: `#jform_title`, but never found it.'. + * These delays allow enough time for the iframe content to fully load, + * Increased from one to two second for slow Intel N95 miniPC. + * This approach works consistently across headless, noVNC, and GUI modes. + * + * If you have a more reliable solution, you are very welcome to improve this implementation. + */ + it('isIframeLoaded()', () => { + // Visit admin's Home Dashboard + cy.visit('/administrator/index.php?option=com_cpanel'); + // Click 'Add module to the dashboard' + cy.get('button.cpanel-add-module').click(); + // Now working with the iFrame + cy.wait(2000); + cy.get('iframe').iframe().then(($body) => { + cy.wrap($body).within(() => { + cy.contains('Frontend Link').click(); + }); + }); + // Open following iFrame + cy.wait(2000); + cy.get('iframe').iframe().then(($body) => { + cy.wrap($body).within(() => { + cy.get('#jform_title').clear().type('test module'); + if (config.instance > 44) { + // Button 'Save & Close' inside iFrame + cy.clickToolbarButton('save & close'); + } + }); + }); + if (config.instance <= 44) { + // Button 'Save & Close' inside iFrame + cy.clickToolbarButton('save & close'); + } + // Delete the module from the Home Dashboard again + // On slow machines (e.g. Intel N95 miniPC) we need to wait that the module is on the page. + cy.wait(2000); + cy.visit('/administrator/index.php?option=com_cpanel'); + // Find the