diff --git a/.codepipeline/docker/config.default.php b/.codepipeline/docker/config.default.php index c8a4e628..a195978b 100644 --- a/.codepipeline/docker/config.default.php +++ b/.codepipeline/docker/config.default.php @@ -13,7 +13,7 @@ //========== Database Configuration ========================== Config::set("database", [ "hostname" => getenv('DB_HOST') ?: "mysqldb", - "port" => getenv('DB_PORT') ?: "", + "port" => getenv('DB_PORT') ?: "3306", "username" => getenv('DB_USERNAME') ?: "cmfive", "password" => getenv('DB_PASSWORD') ?: "cmfive", "database" => getenv('DB_DATABASE') ?: "cmfive", diff --git a/.codepipeline/docker/configs/nginx/default.conf b/.codepipeline/docker/configs/nginx/default.conf index 630d8426..dad99775 100644 --- a/.codepipeline/docker/configs/nginx/default.conf +++ b/.codepipeline/docker/configs/nginx/default.conf @@ -48,7 +48,7 @@ server { # name: deny files extension rule # precedence 4 # deny access to these file extensions - location ~ \.(json|lock|phar|example|xml|md|config|txt|help|html|ds|yml|yaml|sql)$ { + location ~ Dockerfile|\.(json|lock|phar|example|xml|md|config|txt|help|html|ds|yml|yaml|sql|dockerfile|cache|sh)$ { deny all; } diff --git a/.codepipeline/docker/setup.sh b/.codepipeline/docker/setup.sh index d3ef6b18..12740cbb 100755 --- a/.codepipeline/docker/setup.sh +++ b/.codepipeline/docker/setup.sh @@ -27,6 +27,15 @@ if [ ! -f config.php ]; then cp /bootstrap/config.default.php config.php fi +# Add custom config +if [ -n "$CUSTOM_CONFIG" ]; then + echo "➕ Adding custom config" + # Remove existing custom config between markers + sed -i '/# BEGIN CUSTOM CONFIG/,/# END CUSTOM CONFIG/d' config.php + # Add new custom config + echo -e "\n# BEGIN CUSTOM CONFIG\n${CUSTOM_CONFIG}\n# END CUSTOM CONFIG" >> config.php +fi + #Ensure necessary directories have the correct permissions echo "Setting permissions" chmod ugo=rwX -R cache/ storage/ uploads/ diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index bb7cca4d..a12c50cd 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -117,9 +117,12 @@ jobs: done # Pre-requisites Prepare Cmfive Environment - - name: Setup cmfive Test Environment - run: | - docker exec -t cmfive sh -c "chmod -R ugo=rwX /var/www/html*" + + # Tests will assume playwright code is executable + # we should rely on deployment methods already to have provisioned: + # - name: Setup cmfive Test Environment + # run: | + # docker exec -t cmfive sh -c "chmod -R ugo=rwX /var/www/html*" - name: Inject configs into cmfive Test Environment run: | @@ -143,88 +146,9 @@ jobs: echo "⚠️ WARNING: could not find dev tools in boilerplate" fi - - name: Prepare cmfive Test DB - run: | - docker exec -t cmfive sh -c "DB_HOST=mysql-8 DB_USERNAME=root DB_PASSWORD=root DB_DATABASE=$DB_DATABASE DB_PORT=3306 php cmfive.php testDB setup; exit \$?"; - - # Setup Node - - uses: actions/setup-node@v4 - with: - node-version: 20 - - # Run Unit Tests - - name: "Run unit tests" - run: | - docker exec -u root cmfive chmod -R ugo=rwX /var/www/html/test/ - docker exec -u cmfive cmfive sh -c "DB_HOST=mysql-8 DB_USERNAME=$DB_USERNAME DB_PASSWORD=$DB_PASSWORD DB_DATABASE=$DB_DATABASE DB_PORT=3306 php cmfive.php tests unit all; exit \$?" - if [ $? -gt 0 ]; then - echo "Admin module tests failed" - fi - # Setup playwright - - name: Setup Playwright - run: | - echo "Installing Playwright" - cd boilerplate/test/playwright - npm ci - npx playwright install --with-deps - - - name: "Run admin module tests" - run: | - docker exec -u root cmfive sh -c "chmod ugo=rwX -R /var/www/html/system/modules/admin/install/migrations/" - cd boilerplate/test/playwright - npm run build - npm run test --module="admin" --reporter="github" - if [ $? -gt 0 ]; then - echo "Admin module tests failed" - fi - - name: "Run channel module tests" + - name: Run Unit and Playwright tests run: | - cd boilerplate/test/playwright - npm run build - npm run test --module="channel" --reporter="github" - if [ $? -gt 0 ]; then - echo "Channel module tests failed" - fi - - name: "Run form module tests" - run: | - cd boilerplate/test/playwright - npm run build - npm run test --module="form" --reporter="github" - if [ $? -gt 0 ]; then - echo "Form module tests failed" - fi - - name: "Run report module tests" - run: | - cd boilerplate/test/playwright - npm run build - npm run test --module="report" --reporter="github" - if [ $? -gt 0 ]; then - echo "Report module tests failed" - fi - - name: "Run tag module tests" - run: | - cd boilerplate/test/playwright - npm run build - npm run test --module="tag" --reporter="github" - if [ $? -gt 0 ]; then - echo "Tag module tests failed" - fi - - name: "Run task module tests" - run: | - cd boilerplate/test/playwright - npm run build - npm run test --module="task" --reporter="github" - if [ $? -gt 0 ]; then - echo "Task module tests failed" - fi - - name: "Run timelog module tests" - run: | - cd boilerplate/test/playwright - npm run build - npm run test --module="timelog" --reporter="github" - if [ $? -gt 0 ]; then - echo "Timelog module tests failed" - fi + sh ./boilerplate/test/docker_run_tests.sh --cosine_container cmfive - name: Get container logs if: ${{ failure() }} || ${{ success() }} @@ -245,9 +169,8 @@ jobs: if: ${{ failure() }} || ${{ success() }} uses: actions/upload-artifact@v4 with: - name: test-output-${{matrix.node_version}} + name: test-output path: | - boilerplate/test/Codeception/tests/_output/ boilerplate/storage/log/ boilerplate/test/playwright/test-results/ boilerplate/test/playwright/playwright-report/ diff --git a/README.md b/README.md index 2de8588d..1a51d0e6 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ The following options can be used with the Docker image. You may choose to use f - **DB_DATABASE:** The name of the database - **DB_USERNAME:** The username to connect to the database - **DB_PASSWORD:** The password to connect to the database +- **CUSTOM_COFIG:** (optional) Custom configuration to add to the config.php file. - **ENVIRONMENT:** (optional) The environment to run in (development, production). Defaults to production. - **INSTALL_CORE_BRANCH:** (optional) The branch of the cmfive-core repository to switch to while the container is starting. If not specified it will use the built-in core. Note: If this method is used, the theme will not be compiled automatically for the specified branch. diff --git a/composer.phar b/composer.phar index f0461904..4f021d63 100755 Binary files a/composer.phar and b/composer.phar differ diff --git a/docker-compose.yml b/docker-compose.yml index 9515c0ec..e59f0976 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,11 +5,11 @@ services: container_name: mysql-8 hostname: mysql-8 environment: - - MYSQL_ROOT_PASSWORD=root - - MYSQL_USER=cmfive - - MYSQL_PASSWORD=cmfive - - MYSQL_DATABASE=cmfive - - TZ=Australia/Sydney + MYSQL_ROOT_PASSWORD: root + MYSQL_USER: cmfive + MYSQL_PASSWORD: cmfive + MYSQL_DATABASE: cmfive + TZ: Australia/Sydney volumes: - dbdata:/var/lib/mysql:delegated networks: @@ -28,12 +28,15 @@ services: container_name: cmfive hostname: nginx-php8.1 environment: - - TZ=Australia/Sydney - - DB_HOST=mysqldb - - DB_DATABASE=cmfive - - DB_USERNAME=cmfive - - DB_PASSWORD=cmfive - - ENVIRONMENT=development + TZ: Australia/Sydney + DB_HOST: mysqldb + DB_DATABASE: cmfive + DB_USERNAME: cmfive + DB_PASSWORD: cmfive + DB_PORT: 3306 + ENVIRONMENT: development + CUSTOM_CONFIG: | + Config::set('tests', ['testrunner' => 'ENABLED']); volumes: - ./:/var/www/html:rw ports: diff --git a/test/Guide.txt b/test/Guide.txt deleted file mode 100644 index df455087..00000000 --- a/test/Guide.txt +++ /dev/null @@ -1,100 +0,0 @@ - -*** Pull Codeception test branch cm5 boilerplate&core from git -*** Setup Codeception -*** Make sure a Webdriver service is running - - - Use "cmfive.php" for TestRunner functions & as wrapper for command line tools - ---------------------------------------------------------------------- -TestRunner for Codeception: ---------------------------------------------------------------------- - -From "boilerplate", use cmfive.php. -cmfive.php has CLI and menu wrappers to do: - - execute cmfiveTests.php - - build & show all tests - - execute cmfiveTests.php run - - build & run all tests -- execute cmfiveTests.php run [module]_[MyTest]Cest.php - - build all but run only [MyTest] -- eg: execute cmfiveTests.php run boilerplate_HelperCest.php - - build all and show all currently available Cest helper functions - ---------------------------------------------------------------------- - -Extend with: -cmfive-boilerplate\test\Codeception\tests\boilerplate\CmfiveUI.php - --> base actor for all tests --> add functions supporting component/CSS level (not module actions!) -cmfive-boilerplate\test\Codeception\tests\boilerplate\acceptance\helpers\CmfiveSite.php - --> base helper for all tests --> add functions related to instances & services (not cmfive features!) - -Make tests portable in cmfive modules: -General folder layout for tests (see cmfive-boilerplate\system\modules\admin\tests) - /acceptance --> main Codeception test container - - [MyTest]Cest.php files go in here - /acceptance/helpers - - helpers go in here to be shared with other modules - /acceptance/steps - - custom actors go in here if needed, not shared with other modules - ---------------------------------------------------------------------- -TestRunner mechanical details: ---------------------------------------------------------------------- - -TestRunner (boilerplate/cmfiveTests.php) will seek from: -'PROJECT_MODULE_DIRECTORY' (testing CRM) -'SYSTEM_MODULE_DIRECTORY' (testing CORE) - -Finding folders system/[module]/tests: - - - acceptance: - location for this module's 'Cest' tests - can be several files & several tests per file - eg: someTestsCest.php - - - acceptance/helpers - generic usefull functions supporting the module - exposed in 'actor' to all tests for all modules - does not contain 'actor' so needs to be passed "$I" by test code - eg: Helper implements --> function login($I,$username,$password) - Any Cest can say --> $I->login($I,$username,$password); - - - acceptance/steps - allow extension to 'actor' specifically for this module's 'Cest' tests - controls actor by "$this->" and exposes as "$I->" in Cest code - eg: Cest implements --> function testAnAspect(\Step\Acceptance\[NameOfStepActorClass] $I) - Cest has $I with functions from acceptance/steps/[NameOfStepActorClass].php - Step implements --> function doSpecialModuleThing($withThis,$andThat) - Cest can say --> $I->doSpecialModuleThing($thisIs,$thatWas) - -TestRunner also provides: -'WORKFLOWS_TEST_DIRECTORY' (abstract compound tests on CORE) - -Finding folders system/tests/[workflows]: - - - acceptance - - acceptance/helpers - - acceptance/steps - -And: -'BOILERPLATE_TEST_DIRECTORY' (testing CM5/$WEB) - -Finding folder [boilerplate]: - - - CmfiveUI.php: - base class of all test actors per acceptance.suite.dist.yml - generic usefull functions related to page elements, CSS, conversions, Cmfive housekeeping - nothing module specific in here! - - - acceptance: - basic 'Cest' to confirm CM5 is up - - - acceptance/steps - none needed - - - acceptance/helpers - "CmfiveSite.php" containing universal support for all modules - eg: login , clickCmfiveNavbar - - ------------------------------------------------------------------------------- diff --git a/test/Services/LaunchChromeSelenium.sh b/test/Services/LaunchChromeSelenium.sh deleted file mode 100755 index 4209a441..00000000 --- a/test/Services/LaunchChromeSelenium.sh +++ /dev/null @@ -1 +0,0 @@ -java -jar ./selenium-server-standalone-3.14.0.jar diff --git a/test/Services/Windows/LaunchChromeSelenium.bat b/test/Services/Windows/LaunchChromeSelenium.bat deleted file mode 100644 index 107c4624..00000000 --- a/test/Services/Windows/LaunchChromeSelenium.bat +++ /dev/null @@ -1,5 +0,0 @@ - -java -jar .\selenium-server-standalone-3.14.0.jar - -pause - diff --git a/test/Services/Windows/chromedriver.exe b/test/Services/Windows/chromedriver.exe deleted file mode 100644 index 370e9ebe..00000000 Binary files a/test/Services/Windows/chromedriver.exe and /dev/null differ diff --git a/test/Services/Windows/dockerised.bat b/test/Services/Windows/dockerised.bat deleted file mode 100644 index a0fb5341..00000000 --- a/test/Services/Windows/dockerised.bat +++ /dev/null @@ -1 +0,0 @@ -docker run --net=cmfive-boilerplate_default --network-alias=selenium314 -p 4444:4444 selenium/standalone-chrome:3.14.0 \ No newline at end of file diff --git a/test/Services/Windows/geckodriver.exe b/test/Services/Windows/geckodriver.exe deleted file mode 100644 index 041f4a63..00000000 Binary files a/test/Services/Windows/geckodriver.exe and /dev/null differ diff --git a/test/Services/Windows/selenium-server-standalone-3.14.0.jar b/test/Services/Windows/selenium-server-standalone-3.14.0.jar deleted file mode 100644 index daa9c0fe..00000000 Binary files a/test/Services/Windows/selenium-server-standalone-3.14.0.jar and /dev/null differ diff --git a/test/Services/selenium-server-standalone-3.14.0.jar b/test/Services/selenium-server-standalone-3.14.0.jar deleted file mode 100644 index daa9c0fe..00000000 Binary files a/test/Services/selenium-server-standalone-3.14.0.jar and /dev/null differ diff --git a/test/Setup.txt b/test/Setup.txt index d24dad91..24730166 100644 --- a/test/Setup.txt +++ b/test/Setup.txt @@ -1,51 +1,40 @@ -1) Clone/pull/download: https://github.com/2pisoftware/cmfive-boilerplate - - Position it nicely for WebServer to find - - Match it to a CORE install (cmfive.php step[1] will clone main from scratch) - - Make symlinks etc as required - - Apply any other usual cmfive setup steps! - - Enable TestRunner in cmfive-boilerplate\config.php: - Config::set("tests", array( - "testrunner" => "ENABLED" - )); +1) Setup Cosine environment, using end-to-end containers with default/dev/test MySQL container. + - docker-compose in boilerplate root folder will standup up a typical dev/test container deployment + - Manage install & symlinking for CORE and CUSTOM MODULES per the target module code for testing + +2) Check-or-Add settings to your config.php: + + //========== TestRunner Configuration ========================== + Config::set("system.environment", "development"); + Config::set("core_template.foundation.reveal.animation", "none"); + Config::set("core_template.foundation.reveal.animation_speed", 0); + Config::set('tests', ['testrunner' => 'ENABLED']); + + //========== Database Configuration ========================== + Config::set("database", [ + "hostname" => getenv('DB_HOST') ?: "mysqldb", + "port" => getenv('DB_PORT') ?: "3306", + "username" => getenv('DB_USERNAME') ?: "cmfive", + "password" => getenv('DB_PASSWORD') ?: "cmfive", + "database" => getenv('DB_DATABASE') ?: "cmfive", + "driver" => getenv('DB') ?: "mysql", + "backups" => + [ + 'outputExt' => 'sql', + 'commandPath' => [ + 'unix' => '/usr/bin/', + ], + 'backupCommand' => [ + 'unix' => 'mysqldump -u $username -h $hostname -P $port -p\'$password\' $dbname > $filename', + ], + 'restoreCommand' => [ + 'unix' => 'mysql -u $username -h $hostname -P $port -p\'$password\' $dbname < $filename', + ], + ] + ]); + +3) run "docker_run_tests.sh" + - check if you need to run chmod 755 docker_run_tests.sh for permission - FOR TEST ENVIRONMENT --> BEST TO PROCEED FROM HERE WITH DOCKER-"UP" FROM BOILERPLATE COMPOSE YML - - 2) cm5 --> Install - - TestRunner will need a 'volatile' database to work into. - - Use "cmfive.php" to manage chosen cm5 database - - - Create/Check cmfive-boilerplate config.php for all database settings - - use example to correctly configure DB executable commands and paths - - leave parameters as-is; these will be auto-filled - - these settings do not override any settings elsewhere (eg: in Admin module config) - - - CHECK THE CONFIG WORKS -> test for backup and restore, examine files in cmfive-boilerplate\backups - - BE SURE YOU CAN ACCESS A BACKUP - - - Run : "Setup empty TestRunner DB and Administrator" - - once only - - backs up standing DB -> BUT ONLY IF backup config.php is correct! - - deletes all data -> CAN ONLY BE RECOVERED if your backup is good! - - runs all migrations & seeds test Admin user - - grabs snapshot of new 'empty' database to use for tests - -3) Codeception --> Install - - Use "test\.install\install.sh" - - it will get a fresh "composer.phar" & pull Codeception source + modules, - then "BOOTSTRAPS" codeception project environment - - if you cannot use bash, follow all steps in the script per your own OS tools - -4) Selenium support - - provisioned by Docker, copy settings from config.example on config.php - - customise if not using Docker - -5) Check cmfive-boilerplate\test\Codeception\tests\acceptance.suite.dist.yml: - --> needs to match your cmfive WebServer & Browser & WebDriver - - provisioned from config.php - - copy settings from config.example on config.php - - set specifics for your DB (&Selenium if not using from Docker) - -6) Execute in --> cmfive-boilerplate: - --> Use "cmfive.php" for TestRunner functions & as wrapper for command line tools diff --git a/test/docker_run_tests.sh b/test/docker_run_tests.sh new file mode 100755 index 00000000..fcf972f3 --- /dev/null +++ b/test/docker_run_tests.sh @@ -0,0 +1,209 @@ +#!/bin/sh + +# Script will self manage errors: +set +e + +# This script is used to run the Playwright tests in a container +# usage: ./docker_run.sh +# Or to refresh the Cmfive Docker containers before running the tests +# Node version can be specified, WARNING Playwright&Cosine will not be expected to support all node versions! +# usage: ./docker_run.sh --fresh +# usage: ./docker_run.sh --node_ver 18 +# usage: ./docker_run.sh --cosine_container [default is 'cmfive'] + +freshen_all="" +test_node_version="" +cosine_container="cmfive" + +while test $# != 0 +do + case "$1" in + --fresh) freshen_all=true ;; + --node_ver) + shift; test_node_version=$1 ;; + --) shift; break;; + --cosine_container) + shift; cosine_container=$1 ;; + --) shift; break;; + esac + shift +done + +# Bootstrap this script in the Playwright container +if [ -z "$IS_PLAYWRIGHT_CONTAINER" ]; then + + + # Get the directory of the script + TESTDIR=$(dirname -- "$( readlink -f -- "$0"; )";) + + # Go up one directory from DIR until docker-compose.yml is found + PROJECTDIR=$TESTDIR + while [ ! -f "$PROJECTDIR/docker-compose.yml" ]; do + PROJECTDIR="$(dirname "$PROJECTDIR")" + echo "PROJECTDIR: $PROJECTDIR" + echo "TESTDIR: $TESTDIR" + if [ "$PROJECTDIR" = "/" ]; then + echo "Panic: docker-compose.yml not found, be sure to run this script from the test directory" + exit 2 + fi + done + + # if the --fresh flag is set, refresh the Cmfive Docker containers + if [ ! -z $freshen_all ]; then + echo "Refreshing Cmfive Docker containers" + docker compose down -v + docker compose up -d --wait + fi + + system_is_at=$(readlink -f $PROJECTDIR/system) + PAGER=cat + echo ">> CONTAINER LABELS (BOILERPLATE) <<" + echo "====================================" + docker inspect --format='{{range $key, $value := .Config.Labels}}{{$key}}={{$value}}{{println}}{{end}}' cmfive + echo ">> CONTAINER LABELS (CORE COMMIT) <<" + echo "====================================" + echo "VENDOR DIRECTORY:" + docker exec -u cmfive -e PAGER=$PAGER $cosine_container sh -c "cd composer/vendor/2pisoftware/cmfive-core && git log -1 --pretty=format:"CORE_HASH=\"%H\"%nCORE_COMMIT_MSG=\"%s\"%nCORE_REF=\"%D\""" + echo "" + if cd $system_is_at/.. ; then + echo "" + echo ">> TESTS ON BRANCH (CORE COMMIT) <<" + echo "====================================" + echo "MOUNTED CORE from $system_is_at: (this is mounted to /system)" + git log -1 --pretty=format:"CORE_HASH=\"%H\"%nCORE_COMMIT_MSG=\"%s\"%nCORE_REF=\"%D\"" + echo "" + fi + sysdir=`basename "$system_is_at"` + coredir=`dirname "$system_is_at"` + coredir=`basename "$coredir"` + + # Explicitly prep DB for testing: + echo "Backup and snaphsot DB with migrations" + docker exec -u cmfive $cosine_container sh -c "DB_HOST=mysql-8 DB_USERNAME=$DB_USERNAME DB_PASSWORD=$DB_PASSWORD DB_DATABASE=$DB_DATABASE DB_PORT=3306 php cmfive.php testDB setup" + DB_SETUP_EXIT_CODE=$? + if [ $DB_SETUP_EXIT_CODE -ne 0 ]; then + echo "Warning: Failed to setup test DB" + exit $DB_SETUP_EXIT_CODE + fi + echo "Success: Setup test DB" + + # First, Run Unit Tests + docker exec -u cmfive $cosine_container sh -c "DB_HOST=mysql-8 DB_USERNAME=$DB_USERNAME DB_PASSWORD=$DB_PASSWORD DB_DATABASE=$DB_DATABASE DB_PORT=3306 php cmfive.php tests unit all; exit \$?" + UNIT_TESTS_EXIT_CODE=$? + if [ $UNIT_TESTS_EXIT_CODE -ne 0 ]; then + echo "Unit tests failed: $UNIT_TESTS_EXIT_CODE" + exit $UNIT_TESTS_EXIT_CODE + fi + echo "Unit tests passed" + + docker build -t playwright-cosine -f $TESTDIR/test_service.Dockerfile $PROJECTDIR + + # Tests SHOULD assume playwright code is executable + # but if this script is not -x- the container won't launch! + # sudo chmod 755 $TESTDIR/docker_run_tests.sh + + echo "" + echo "Tests will collate from: /$coredir/$sysdir" + echo "and from: /cmfive-boilerplate/modules" + docker run -t --rm \ + -e IS_PLAYWRIGHT_CONTAINER=1 \ + -e LANG=en_AU.UTF-8 \ + -e LC_ALL=en_AU.UTF-8 \ + -e TEST_NODE_VERSION=$test_node_version \ + -v ms-playwright-data-cmfive:/ms-playwright \ + -v $PROJECTDIR:/cmfive-boilerplate \ + -v $system_is_at:"/$coredir/$sysdir" \ + --ipc=host \ + --network=host \ + --cap-add=SYS_ADMIN \ + playwright-cosine \ + "/cmfive-boilerplate/test/docker_run_tests.sh" + + DOCKER_EXIT_CODE=$? + + set -e + + # OK, now we are done with the Playwright container + # Consider cleanup: + # We can hold the DB as-is, for further manual testing. + # But should clean up migration artefacts, to avoid git diff. + cd $TESTDIR/playwright + bash ./cleanupTestMigrations.sh --no-confirm + # but no: npm run cleanup + + if [ $DOCKER_EXIT_CODE -ne 0 ]; then + echo "Playwright container exited with code $DOCKER_EXIT_CODE" + exit $DOCKER_EXIT_CODE + fi + + echo "Success: Playwright tests completed" + exit +fi + +wait_for_response() { + local url=$1 + local timeout=$2 + + echo "Waiting for $url to respond" + for i in $(seq 1 $timeout); do + if curl -s -o /dev/null -w "%{http_code}" "$url"; then + echo -n "." + break + fi + sleep 1 + done + + if [ $i -eq $timeout ]; then + echo "Failed to get a response from $url" + exit 1 + fi + echo "" + echo "$url responded" +} + +wait_for_response "http://localhost:3000" 60 + +# Tests will assume playwright code is executable +# we should rely on deployment methods already to have provisioned: +# chmod -R 755 . +whoami +locale +date + +# if TEST_NODE_VERSION is set, adopt version + +if [ ! -z $TEST_NODE_VERSION ]; then + echo "Switching node version" + n $TEST_NODE_VERSION + hash -r +fi + +echo "" +echo "Node is reporting:" +node --version + +cd /cmfive-boilerplate/test/playwright + +echo "DB snapshot is latest from:" +ls ../Databases -lah + +npm ci +npx playwright install --with-deps +npm run build +ls src -lah + +# Run the tests, recommended 1 worker for Playwright for memory usage +export WORKERS=1 + +# Retry failed tests, recommended 0 retries because of data consistency +export RETRIES=0 + +npm run test +PLAYWRIGHT_TESTS_EXIT_CODE=$? + if [ $PLAYWRIGHT_TESTS_EXIT_CODE -ne 0 ]; then + echo "Playwright tests failed: $PLAYWRIGHT_TESTS_EXIT_CODE" + exit $PLAYWRIGHT_TESTS_EXIT_CODE + fi + +echo "Playwright tests passed" + diff --git a/test/playwright/cleanupTestMigrations.sh b/test/playwright/cleanupTestMigrations.sh index ce9d6747..b06b6148 100755 --- a/test/playwright/cleanupTestMigrations.sh +++ b/test/playwright/cleanupTestMigrations.sh @@ -38,10 +38,14 @@ if [ ${#deletable[@]} -ne 0 ]; then done echo -e -n "\033[0m" - echo - echo -e "\033[0;33m" - read -p "Do you want to delete the files you have permission to delete? (y/n) " confirm_delete - echo -e "\033[0m" + if [ "$1" == "--no-confirm" ]; then + confirm_delete=Y + else + echo + echo -e "\033[0;33m" + read -p "Do you want to delete the files you have permission to delete? (y/n) " confirm_delete + echo -e "\033[0m" + fi if [[ "$confirm_delete" =~ ^[Yy]$ ]]; then for file in "${deletable[@]}"; do diff --git a/test/playwright/docker_run.sh b/test/playwright/docker_run.sh deleted file mode 100755 index 2b065008..00000000 --- a/test/playwright/docker_run.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh - -# This script is used to run the Playwright tests in a container -# usage: ./docker_run.sh -# Or to refresh the Cmfive Docker containers before running the tests -# usage: ./docker_run.sh --fresh - -# Bootstrap this script in the Playwright container -if [ -z "$IS_PLAYWRIGHT_CONTAINER" ]; then - # Get the directory of the script - TESTDIR=$(dirname -- "$( readlink -f -- "$0"; )";) - - # Go up one directory from DIR until docker-compose.yml is found - PROJECTDIR=$TESTDIR - while [ ! -f "$PROJECTDIR/docker-compose.yml" ]; do - PROJECTDIR="$(dirname "$PROJECTDIR")" - done - - # if the --fresh flag is set, refresh the Cmfive Docker containers - if [ "$1" = "--fresh" ]; then - echo "Refreshing Cmfive Docker containers" - docker compose down -v - docker compose up -d --wait - fi - - docker run -it --rm \ - -e IS_PLAYWRIGHT_CONTAINER=1 \ - -v $PROJECTDIR:/cmfive-boilerplate \ - -v ms-playwright-data-cmfive:/ms-playwright \ - --ipc=host \ - --network=host \ - --user $(id -u):$(id -g) \ - --cap-add=SYS_ADMIN \ - mcr.microsoft.com/playwright:v1.45.1-jammy \ - /cmfive-boilerplate/test/playwright/docker_run.sh - - # Open ./test-results in the default file manager - if [ -d $TESTDIR/test-results ]; then - if which xdg-open > /dev/null; then - xdg-open $TESTDIR/test-results - elif which open > /dev/null; then - open $TESTDIR/test-results - fi - fi - - exit -fi - -wait_for_response() { - local url=$1 - local timeout=$2 - - echo "Waiting for $url to respond" - for i in $(seq 1 $timeout); do - if curl -s -o /dev/null -w "%{http_code}" "$url"; then - echo -n "." - break - fi - sleep 1 - done - - if [ $i -eq $timeout ]; then - echo "Failed to get a response from $url" - exit 1 - fi - echo "" - echo "$url responded" -} - -cd /cmfive-boilerplate/test/playwright - -npm i -npx playwright install -npm run setup -npm run build -npm run cleanup - -wait_for_response "http://localhost:3000" 30 - -export WORKERS=3 -export RETRIES=2 - -npm run test - diff --git a/test/test_service.Dockerfile b/test/test_service.Dockerfile new file mode 100644 index 00000000..a386b819 --- /dev/null +++ b/test/test_service.Dockerfile @@ -0,0 +1,18 @@ +FROM mcr.microsoft.com/playwright:latest +# Australianise things: +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y locales && \ + locale-gen en_AU.UTF-8 && \ + update-locale en_AU.UTF-8 && \ + LANG=en_AU.UTF-8 && \ + LC_ALL=en_AU.UTF-8 && \ + locale + +RUN apt-get update && \ + npm install -g n && \ + DEBIAN_FRONTEND=noninteractive apt-get install -yq tzdata && \ + ln -fs /usr/share/zoneinfo/Australia/Sydney /etc/localtime && \ + dpkg-reconfigure -f noninteractive tzdata && \ + date + +# Shift into test environment +WORKDIR /cmfive-boilerplate/test/playwright