From 350bb6e5648ed63c7086a9bd89f5acb194a5c85f Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Wed, 17 Aug 2022 10:55:12 -0400 Subject: [PATCH] CI (#8) * wip: json and py validate, semantic, and frappe json diff * test: stub UI test yaml - copied from Frappe * test: add helper shell files, remove job contitionals * test: remove producer/consumer test dbs from install script * test: correct install file / install dependency file * test: echo helper folder to debug path error * test: move helper folder out of workflows * test: remove echo * test: install erpnext * test: create site in sintall script * test: skip assets on erpnext install * test: remove frappe-path argument from bench init * wip: update JSON ci * test: remove python setup, already in ubuntu * test: frappe-bench needs 3.10 * test: python3.9 * test: no mariadb password * test: blank password * test: mysql password 123 * test: using frappe/erpnext workflow * test: allow empty password = yes * test: file wasnt saved * test: mariadb version 10.5 => 10.3 * test: various * test: reinsert pip install * test: fix typo * test: remove space (typo) * test: fix syntax * test: remove site setup * test: restore site without building frappe * test: remove db setup, only ui test * test: remove strawberry output for site setup * test: use check run test * test: cypress test data path * test: install apps on site * test: cypress path * test: bench restart after install, set developer mode * test: CI=Yes bench command * test: install apps * test: add site adn skip assets * test: ci=yes install-app * test: wildcard frappe user, remove ci bench install-app * test: update localhost wildcard both commands * text: bench execute command * test: revert mariadb wildcard and install-app * test: remove bench restart * test: remove CI=yes execute * wip: cypress testing fixup * wip: ach workflows * wip: ach generation * wip: check run ui tests V1 * test: fix cypress command path * test: cypress command * test: cypress response timeout * test: remove headless * test: cypress action * test: rerun * test: "8000" + "/" * test: use cypress config * test: add bench restart * test: update baseUrl to match site_config.json * test: no recordings * test: video, screenshots off * wip: remove unused env vars, set script clone depth, remove commented yarn run, fix spec.js typo Co-authored-by: Robert Duncan --- .github/helper/install.sh | 42 +++++++++ .github/helper/install_dependencies.sh | 16 ++++ .github/helper/site_config.json | 17 ++++ .github/workflows/main.yml | 105 +++++++++++++++++++++ .github/workflows/ui_test.yaml | 97 +++++++++++++++++++ cypress.json | 4 +- cypress/integration/check_run.spec.js | 46 +++++++++ cypress/integration/check_run_list.spec.js | 18 ---- cypress/integration/employee.spec.js | 0 cypress/integration/supplier.spec.js | 0 10 files changed, 326 insertions(+), 19 deletions(-) create mode 100644 .github/helper/install.sh create mode 100644 .github/helper/install_dependencies.sh create mode 100644 .github/helper/site_config.json create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/ui_test.yaml delete mode 100644 cypress/integration/check_run_list.spec.js delete mode 100644 cypress/integration/employee.spec.js delete mode 100644 cypress/integration/supplier.spec.js diff --git a/.github/helper/install.sh b/.github/helper/install.sh new file mode 100644 index 00000000..1a4b163e --- /dev/null +++ b/.github/helper/install.sh @@ -0,0 +1,42 @@ +#!/bin/bash + + +cd ~ || exit + +pip install frappe-bench +git clone https://github.com/frappe/frappe --branch version-13 --depth 1 +bench init --skip-assets --frappe-path ~/frappe --python "$(which python)" frappe-bench + +mkdir ~/frappe-bench/sites/test_site +cp -r "${GITHUB_WORKSPACE}/.github/helper/site_config.json" ~/frappe-bench/sites/test_site + +mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL character_set_server = 'utf8mb4'" +mysql --host 127.0.0.1 --port 3306 -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'" + +mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'" +mysql --host 127.0.0.1 --port 3306 -u root -e "CREATE DATABASE test_frappe" +mysql --host 127.0.0.1 --port 3306 -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'" + +mysql --host 127.0.0.1 --port 3306 -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'" +mysql --host 127.0.0.1 --port 3306 -u root -e "FLUSH PRIVILEGES" + +cd ./frappe-bench || exit + +sed -i 's/^watch:/# watch:/g' Procfile +sed -i 's/^schedule:/# schedule:/g' Procfile + +sed -i 's/^socketio:/# socketio:/g' Procfile; +sed -i 's/^redis_socketio:/# redis_socketio:/g' Procfile; + +bench setup requirements --node + +cd ./apps/frappe || exit +yarn add node-sass@4.13.1 +cd ../.. + +bench get-app erpnext --branch version-13 +bench get-app check_run "${GITHUB_WORKSPACE}" + +bench start &> bench_run_logs.txt & +bench --site test_site reinstall --yes +CI=Yes bench build diff --git a/.github/helper/install_dependencies.sh b/.github/helper/install_dependencies.sh new file mode 100644 index 00000000..2ea8fd23 --- /dev/null +++ b/.github/helper/install_dependencies.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Check for merge conflicts before proceeding +python -m compileall -f "${GITHUB_WORKSPACE}" +if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}" + then echo "Found merge conflicts" + exit 1 +fi + +sudo apt update && sudo apt install redis-server libcups2-dev + + # install wkhtmltopdf +wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz +tar -xf /tmp/wkhtmltox.tar.xz -C /tmp +sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf +sudo chmod o+x /usr/local/bin/wkhtmltopdf diff --git a/.github/helper/site_config.json b/.github/helper/site_config.json new file mode 100644 index 00000000..9c82702d --- /dev/null +++ b/.github/helper/site_config.json @@ -0,0 +1,17 @@ +{ + "db_host": "127.0.0.1", + "db_port": 3306, + "db_name": "test_frappe", + "db_password": "test_frappe", + "auto_email_id": "test@example.com", + "mail_server": "smtp.example.com", + "mail_login": "test@example.com", + "mail_password": "test", + "admin_password": "admin", + "root_login": "root", + "root_password": "travis", + "host_name": "http://test_site:8000", + "install_apps": ["erpnext", "check_run"], + "throttle_user_limit": 100, + "developer_mode": 1 +} \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..86fa2081 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,105 @@ +name: Validate Diff Release +on: + push: + branches: [ version-13 ] + pull_request: + branches: [ version-13 ] + +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + Diff: + needs: [ Validate_PY_JSON_MERGE ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + fetch-depth: 2 + + - name: Find changed json + id: changed-json + uses: tj-actions/changed-files@v23.1 + with: + files: | + **/*.json + include_all_old_new_renamed_files: true + + - name: Copy head paths files + run: | + mkdir head + touch head/acmr.txt + for file in ${{ steps.changed-json.outputs.added_files }}; do + echo "A,head/${file}" >> head/acmr.txt + cp --parents $file head/ + done + for file in ${{ steps.changed-json.outputs.copied_files }}; do + echo "C,head/${file}" >> head/acmr.txt + cp --parents $file head/ + done + for file in ${{ steps.changed-json.outputs.modified_files }}; do + echo "M,head/${file}" >> head/acmr.txt + cp --parents $file head/ + done + for file in ${{ steps.changed-json.outputs.renamed_files }}; do + echo "R,head/${file}" >> head/acmr.txt + cp --parents $file head/ + done + + - name: Checkout base + run: git checkout $(git --no-pager log --oneline -n 2 | awk 'NR==2 {print $1}') + + - name: Copy base paths + run: | + mkdir base + touch base/mrd.txt + for file in ${{ steps.changed-json.outputs.modified_files }}; do + echo "M,${file}" >> base/mrd.txt + done + for file in ${{ steps.changed-json.outputs.all_old_new_renamed_files }}; do + echo "R,${file}" >> base/mrd.txt + done + for file in ${{ steps.changed-json.outputs.deleted_files }}; do + echo "D,${file}" >> base/mrd.txt + done + + - name: Setup requirements and script + run: | + pip install rich + pip install json_source_map + git clone --depth 1 https://gist.github.com/74017707b676c3ce947528fb00dd46d0.git fsjd + + - name: Diff table + run: python3 fsjd/frappe_schema_json_diff.py base/mrd.txt head/acmr.txt 1 + + + Release: + needs: [ Validate_PY_JSON_MERGE ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Release + run: npx semantic-release + + Validate_PY_JSON_MERGE: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Get validate_json + run: git clone --depth 1 https://gist.github.com/f1bf2c11f78331b2417189c385022c28.git validate_json + + - name: Validate json + run: python3 validate_json/validate_json.py ./ + + - name: Compile + run: python3 -m compileall -q ./ + + - name: Check merge + run: | + if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}" + then echo "Found merge conflicts" + exit 1 + fi + \ No newline at end of file diff --git a/.github/workflows/ui_test.yaml b/.github/workflows/ui_test.yaml new file mode 100644 index 00000000..735c36ef --- /dev/null +++ b/.github/workflows/ui_test.yaml @@ -0,0 +1,97 @@ +name: UI + +on: + pull_request: + workflow_dispatch: + +jobs: + cypress-run: + runs-on: ubuntu-20.04 + timeout-minutes: 25 + + name: UI Tests (Cypress) + services: + mysql: + image: mariadb:10.3 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: YES + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 + + steps: + - name: Clone + uses: actions/checkout@v2 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.8' + + - uses: actions/setup-node@v2 + with: + node-version: '12' + check-latest: true + + - name: Add to Hosts + run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts + + - name: Cache pip + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + ${{ runner.os }}- + + - name: Cache node modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v2 + id: yarn-cache + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Cache cypress binary + uses: actions/cache@v2 + with: + path: ~/.cache + key: ${{ runner.os }}-cypress- + restore-keys: | + ${{ runner.os }}-cypress- + ${{ runner.os }}- + + - name: Install Dependencies + run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh + + - name: Install + run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh + + - name: Check Run Setup + run: | + cd ~/frappe-bench + bench --site test_site execute 'check_run.test_setup.before_test' + + - name: Cypress run + uses: cypress-io/github-action@v4 + with: + spec: cypress/integration/* + config-file: cypress.json + \ No newline at end of file diff --git a/cypress.json b/cypress.json index 7bf58640..75fbaf0b 100644 --- a/cypress.json +++ b/cypress.json @@ -1,7 +1,9 @@ { - "baseUrl": "http://localhost:8038", + "baseUrl": "http://test_site:8000", "adminPassword": "admin", "defaultCommandTimeout": 20000, + "video": false, + "screenshotOnRunFailure": false, "pageLoadTimeout": 15000, "retries": { "runMode": 2, diff --git a/cypress/integration/check_run.spec.js b/cypress/integration/check_run.spec.js index e69de29b..3e77b3fe 100644 --- a/cypress/integration/check_run.spec.js +++ b/cypress/integration/check_run.spec.js @@ -0,0 +1,46 @@ +context('Check Run List', () => { + before(() => { + cy.visit('/login') + cy.login() + cy.go_to_list('Check Run') + }) + + it("Add Check Run", () => { + cy.get('.primary-action').contains('Add Check Run').should('be.visible').click() + cy.wait(1000) + cy.get_field('company').focus().should('be.visible') + cy.get_field('bank_account').focus().should('be.visible') + cy.get_field('pay_to_account').focus().should('be.visible') + cy.get('.btn-primary').contains('Start Check Run').should('be.visible').click() + }) + + it("Complete First Check Run", () => { + cy.visit('/app/check-run/ACC-CR-2022-00001') + cy.fill_field("end_date", "1/1").blur() + cy.fill_field("posting_date", "1/1").blur() + cy.get('[data-checkbox-index="0"]').click().wait(250) + cy.get('[data-fieldname="amount_check_run"]').get('.like-disabled-input').should('contain', '$ 1,800.00') + cy.get('body').type(' ').wait(250) + cy.get('[data-fieldname="amount_check_run"]').get('.like-disabled-input').should('contain', '$ 0.00').wait(250) + cy.get('#select-all').click() + cy.get('.primary-action').contains('Save').should('be.visible').click() + cy.get('.primary-action').contains('Submit').should('be.visible').click().wait(250) + cy.get_open_dialog().contains('Yes').should('be.visible').click() + cy.get('.indicator-pill').should('contain', 'Submitted').wait(250) + cy.get('.indicator-pill').should('contain', 'Ready to Print').wait(15000) + }) + + it("Complete Second Check Run", () => { + cy.get('body').type('{ctrl+b}').wait(500) + cy.fill_field("end_date", "1/1").blur() + cy.fill_field("posting_date", "1/1").blur() + cy.get_field("pay_to_account").type("{ctrl+home}{del}").blur().wait(100) + cy.fill_field("pay_to_account", "2120 - Payroll Payable - CFC").blur().wait(500) + cy.get('#select-all').click() + cy.get('.primary-action').contains('Save').should('be.visible').click() + cy.get('.primary-action').contains('Submit').should('be.visible').click().wait(250) + cy.get_open_dialog().contains('Yes').should('be.visible').click() + cy.get('.indicator-pill').should('contain', 'Submitted').wait(250) + cy.get('.indicator-pill').should('contain', 'Ready to Print').wait(7000) + }) +}) \ No newline at end of file diff --git a/cypress/integration/check_run_list.spec.js b/cypress/integration/check_run_list.spec.js deleted file mode 100644 index a5c889f2..00000000 --- a/cypress/integration/check_run_list.spec.js +++ /dev/null @@ -1,18 +0,0 @@ -context('Check Run List', () => { - before(() => { - cy.visit('/login') - cy.login() - cy.go_to_list('Check Run') - }) - - it("Create a new Check Run", () => { - cy.get('.primary-action').contains('Add Check Run').should('be.visible').click() - cy.wait(500) - cy.get_field('company').focus().should('be.visible') - cy.get_field('bank_account').focus().should('be.visible') - cy.get_field('pay_to_account').focus().should('be.visible') - cy.fill_field("bank_account", "Primary Checking - Local Bank").blur() - cy.fill_field("pay_to_account", "Local Bank - CFC").blur() - cy.get('.btn-primary').contains('Save').should('be.visible').click() - }) -}) \ No newline at end of file diff --git a/cypress/integration/employee.spec.js b/cypress/integration/employee.spec.js deleted file mode 100644 index e69de29b..00000000 diff --git a/cypress/integration/supplier.spec.js b/cypress/integration/supplier.spec.js deleted file mode 100644 index e69de29b..00000000