@@ -9,6 +9,6 @@ trim_trailing_whitespace = true | |||||
charset = utf-8 | charset = utf-8 | ||||
# python, js indentation settings | # python, js indentation settings | ||||
[{*.py,*.js}] | |||||
[{*.py,*.js,*.vue}] | |||||
indent_style = tab | indent_style = tab | ||||
indent_size = 4 | indent_size = 4 |
@@ -10,3 +10,6 @@ | |||||
# Replace use of Class.extend with native JS class | # Replace use of Class.extend with native JS class | ||||
fe20515c23a3ac41f1092bf0eaf0a0a452ec2e85 | fe20515c23a3ac41f1092bf0eaf0a0a452ec2e85 | ||||
# Updating license headers | |||||
34460265554242a8d05fb09f049033b1117e1a2b |
@@ -32,9 +32,9 @@ if __name__ == "__main__": | |||||
if response.ok: | if response.ok: | ||||
payload = response.json() | payload = response.json() | ||||
title = payload.get("title", "").lower() | |||||
head_sha = payload.get("head", {}).get("sha") | |||||
body = payload.get("body", "").lower() | |||||
title = (payload.get("title") or "").lower() | |||||
head_sha = (payload.get("head") or {}).get("sha") | |||||
body = (payload.get("body") or "").lower() | |||||
if title.startswith("feat") and head_sha and "no-docs" not in body: | if title.startswith("feat") and head_sha and "no-docs" not in body: | ||||
if docs_link_exists(body): | if docs_link_exists(body): | ||||
@@ -2,11 +2,6 @@ | |||||
set -e | set -e | ||||
# python "${GITHUB_WORKSPACE}/.github/helper/roulette.py" | |||||
# if [[ $? != 2 ]];then | |||||
# exit; | |||||
# fi | |||||
# install wkhtmltopdf | # install wkhtmltopdf | ||||
wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz | 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 | tar -xf /tmp/wkhtmltox.tar.xz -C /tmp | ||||
@@ -1,56 +1,72 @@ | |||||
# if the script ends with exit code 0, then no tests are run further, else all tests are run | |||||
import json | |||||
import os | import os | ||||
import re | import re | ||||
import shlex | import shlex | ||||
import subprocess | import subprocess | ||||
import sys | import sys | ||||
import urllib.request | |||||
def get_files_list(pr_number, repo="frappe/frappe"): | |||||
req = urllib.request.Request(f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files") | |||||
res = urllib.request.urlopen(req) | |||||
dump = json.loads(res.read().decode('utf8')) | |||||
return [change["filename"] for change in dump] | |||||
def get_output(command, shell=True): | def get_output(command, shell=True): | ||||
print(command) | |||||
command = shlex.split(command) | |||||
return subprocess.check_output(command, shell=shell, encoding="utf8").strip() | |||||
print(command) | |||||
command = shlex.split(command) | |||||
return subprocess.check_output(command, shell=shell, encoding="utf8").strip() | |||||
def is_py(file): | def is_py(file): | ||||
return file.endswith("py") | |||||
return file.endswith("py") | |||||
def is_ci(file): | |||||
return ".github" in file | |||||
def is_js(file): | |||||
return file.endswith("js") | |||||
def is_frontend_code(file): | |||||
return file.lower().endswith((".css", ".scss", ".less", ".sass", ".styl", ".js", ".ts", ".vue")) | |||||
def is_docs(file): | def is_docs(file): | ||||
regex = re.compile(r'\.(md|png|jpg|jpeg)$|^.github|LICENSE') | |||||
return bool(regex.search(file)) | |||||
regex = re.compile(r'\.(md|png|jpg|jpeg|csv)$|^.github|LICENSE') | |||||
return bool(regex.search(file)) | |||||
if __name__ == "__main__": | if __name__ == "__main__": | ||||
build_type = os.environ.get("TYPE") | |||||
before = os.environ.get("BEFORE") | |||||
after = os.environ.get("AFTER") | |||||
commit_range = before + '...' + after | |||||
print("Build Type: {}".format(build_type)) | |||||
print("Commit Range: {}".format(commit_range)) | |||||
try: | |||||
files_changed = get_output("git diff --name-only {}".format(commit_range), shell=False) | |||||
except Exception: | |||||
sys.exit(2) | |||||
if "fatal" not in files_changed: | |||||
files_list = files_changed.split() | |||||
only_docs_changed = len(list(filter(is_docs, files_list))) == len(files_list) | |||||
only_js_changed = len(list(filter(is_js, files_list))) == len(files_list) | |||||
only_py_changed = len(list(filter(is_py, files_list))) == len(files_list) | |||||
if only_docs_changed: | |||||
print("Only docs were updated, stopping build process.") | |||||
sys.exit(0) | |||||
if only_js_changed and build_type == "server": | |||||
print("Only JavaScript code was updated; Stopping Python build process.") | |||||
sys.exit(0) | |||||
if only_py_changed and build_type == "ui": | |||||
print("Only Python code was updated, stopping Cypress build process.") | |||||
sys.exit(0) | |||||
sys.exit(2) | |||||
files_list = sys.argv[1:] | |||||
build_type = os.environ.get("TYPE") | |||||
pr_number = os.environ.get("PR_NUMBER") | |||||
repo = os.environ.get("REPO_NAME") | |||||
# this is a push build, run all builds | |||||
if not pr_number: | |||||
os.system('echo "::set-output name=build::strawberry"') | |||||
sys.exit(0) | |||||
files_list = files_list or get_files_list(pr_number=pr_number, repo=repo) | |||||
if not files_list: | |||||
print("No files' changes detected. Build is shutting") | |||||
sys.exit(0) | |||||
ci_files_changed = any(f for f in files_list if is_ci(f)) | |||||
only_docs_changed = len(list(filter(is_docs, files_list))) == len(files_list) | |||||
only_frontend_code_changed = len(list(filter(is_frontend_code, files_list))) == len(files_list) | |||||
only_py_changed = len(list(filter(is_py, files_list))) == len(files_list) | |||||
if ci_files_changed: | |||||
print("CI related files were updated, running all build processes.") | |||||
elif only_docs_changed: | |||||
print("Only docs were updated, stopping build process.") | |||||
sys.exit(0) | |||||
elif only_frontend_code_changed and build_type == "server": | |||||
print("Only Frontend code was updated; Stopping Python build process.") | |||||
sys.exit(0) | |||||
elif only_py_changed and build_type == "ui": | |||||
print("Only Python code was updated, stopping Cypress build process.") | |||||
sys.exit(0) | |||||
os.system('echo "::set-output name=build::strawberry"') |
@@ -2,6 +2,11 @@ name: Patch | |||||
on: [pull_request, workflow_dispatch] | on: [pull_request, workflow_dispatch] | ||||
concurrency: | |||||
group: patch-mariadb-develop-${{ github.event.number }} | |||||
cancel-in-progress: true | |||||
jobs: | jobs: | ||||
test: | test: | ||||
runs-on: ubuntu-18.04 | runs-on: ubuntu-18.04 | ||||
@@ -26,10 +31,21 @@ jobs: | |||||
with: | with: | ||||
python-version: 3.7 | python-version: 3.7 | ||||
- name: Check if build should be run | |||||
id: check-build | |||||
run: | | |||||
python "${GITHUB_WORKSPACE}/.github/helper/roulette.py" | |||||
env: | |||||
TYPE: "server" | |||||
PR_NUMBER: ${{ github.event.number }} | |||||
REPO_NAME: ${{ github.repository }} | |||||
- name: Add to Hosts | - name: Add to Hosts | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | ||||
- name: Cache pip | - name: Cache pip | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
with: | with: | ||||
path: ~/.cache/pip | path: ~/.cache/pip | ||||
@@ -39,6 +55,7 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Cache node modules | - name: Cache node modules | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
env: | env: | ||||
cache-name: cache-node-modules | cache-name: cache-node-modules | ||||
@@ -51,10 +68,12 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Get yarn cache directory path | - name: Get yarn cache directory path | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache-dir-path | id: yarn-cache-dir-path | ||||
run: echo "::set-output name=dir::$(yarn cache dir)" | run: echo "::set-output name=dir::$(yarn cache dir)" | ||||
- uses: actions/cache@v2 | - uses: actions/cache@v2 | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache | id: yarn-cache | ||||
with: | with: | ||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
@@ -63,6 +82,7 @@ jobs: | |||||
${{ runner.os }}-yarn- | ${{ runner.os }}-yarn- | ||||
- name: Install Dependencies | - name: Install Dependencies | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | ||||
env: | env: | ||||
BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | ||||
@@ -70,12 +90,14 @@ jobs: | |||||
TYPE: server | TYPE: server | ||||
- name: Install | - name: Install | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | ||||
env: | env: | ||||
DB: mariadb | DB: mariadb | ||||
TYPE: server | TYPE: server | ||||
- name: Run Patch Tests | - name: Run Patch Tests | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: | | run: | | ||||
cd ~/frappe-bench/ | cd ~/frappe-bench/ | ||||
wget https://frappeframework.com/files/v10-frappe.sql.gz | wget https://frappeframework.com/files/v10-frappe.sql.gz | ||||
@@ -6,6 +6,11 @@ on: | |||||
push: | push: | ||||
branches: [ develop ] | branches: [ develop ] | ||||
concurrency: | |||||
group: server-mariadb-develop-${{ github.event.number }} | |||||
cancel-in-progress: true | |||||
jobs: | jobs: | ||||
test: | test: | ||||
runs-on: ubuntu-18.04 | runs-on: ubuntu-18.04 | ||||
@@ -35,17 +40,29 @@ jobs: | |||||
with: | with: | ||||
python-version: 3.7 | python-version: 3.7 | ||||
- name: Check if build should be run | |||||
id: check-build | |||||
run: | | |||||
python "${GITHUB_WORKSPACE}/.github/helper/roulette.py" | |||||
env: | |||||
TYPE: "server" | |||||
PR_NUMBER: ${{ github.event.number }} | |||||
REPO_NAME: ${{ github.repository }} | |||||
- uses: actions/setup-node@v2 | - uses: actions/setup-node@v2 | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
with: | with: | ||||
node-version: 14 | node-version: 14 | ||||
check-latest: true | check-latest: true | ||||
- name: Add to Hosts | - name: Add to Hosts | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: | | run: | | ||||
echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | ||||
echo "127.0.0.1 test_site_producer" | sudo tee -a /etc/hosts | echo "127.0.0.1 test_site_producer" | sudo tee -a /etc/hosts | ||||
- name: Cache pip | - name: Cache pip | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
with: | with: | ||||
path: ~/.cache/pip | path: ~/.cache/pip | ||||
@@ -55,6 +72,7 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Cache node modules | - name: Cache node modules | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
env: | env: | ||||
cache-name: cache-node-modules | cache-name: cache-node-modules | ||||
@@ -67,10 +85,12 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Get yarn cache directory path | - name: Get yarn cache directory path | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache-dir-path | id: yarn-cache-dir-path | ||||
run: echo "::set-output name=dir::$(yarn cache dir)" | run: echo "::set-output name=dir::$(yarn cache dir)" | ||||
- uses: actions/cache@v2 | - uses: actions/cache@v2 | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache | id: yarn-cache | ||||
with: | with: | ||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
@@ -79,6 +99,7 @@ jobs: | |||||
${{ runner.os }}-yarn- | ${{ runner.os }}-yarn- | ||||
- name: Install Dependencies | - name: Install Dependencies | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | ||||
env: | env: | ||||
BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | ||||
@@ -86,45 +107,23 @@ jobs: | |||||
TYPE: server | TYPE: server | ||||
- name: Install | - name: Install | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | ||||
env: | env: | ||||
DB: mariadb | DB: mariadb | ||||
TYPE: server | TYPE: server | ||||
- name: Run Tests | - name: Run Tests | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --use-orchestrator --with-coverage | run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --use-orchestrator --with-coverage | ||||
env: | env: | ||||
CI_BUILD_ID: ${{ github.run_id }} | CI_BUILD_ID: ${{ github.run_id }} | ||||
ORCHESTRATOR_URL: http://test-orchestrator.frappe.io | ORCHESTRATOR_URL: http://test-orchestrator.frappe.io | ||||
- name: Upload Coverage Data | |||||
run: | | |||||
cp ~/frappe-bench/sites/.coverage ${GITHUB_WORKSPACE} | |||||
cd ${GITHUB_WORKSPACE} | |||||
pip3 install coverage==5.5 | |||||
pip3 install coveralls==3.0.1 | |||||
coveralls | |||||
env: | |||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |||||
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} | |||||
COVERALLS_FLAG_NAME: run-${{ matrix.container }} | |||||
COVERALLS_SERVICE_NAME: ${{ github.event_name == 'pull_request' && 'github' || 'github-actions' }} | |||||
COVERALLS_PARALLEL: true | |||||
coveralls: | |||||
name: Coverage Wrap Up | |||||
needs: test | |||||
container: python:3-slim | |||||
runs-on: ubuntu-18.04 | |||||
steps: | |||||
- name: Clone | |||||
uses: actions/checkout@v2 | |||||
- name: Coveralls Finished | |||||
run: | | |||||
cd ${GITHUB_WORKSPACE} | |||||
pip3 install coverage==5.5 | |||||
pip3 install coveralls==3.0.1 | |||||
coveralls --finish | |||||
env: | |||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |||||
- name: Upload coverage data | |||||
uses: codecov/codecov-action@v2 | |||||
with: | |||||
name: MariaDB | |||||
fail_ci_if_error: true | |||||
files: /home/runner/frappe-bench/sites/coverage.xml | |||||
verbose: true |
@@ -3,6 +3,12 @@ name: Server | |||||
on: | on: | ||||
pull_request: | pull_request: | ||||
workflow_dispatch: | workflow_dispatch: | ||||
push: | |||||
branches: [ develop ] | |||||
concurrency: | |||||
group: server-postgres-develop-${{ github.event.number }} | |||||
cancel-in-progress: true | |||||
jobs: | jobs: | ||||
test: | test: | ||||
@@ -37,17 +43,29 @@ jobs: | |||||
with: | with: | ||||
python-version: 3.7 | python-version: 3.7 | ||||
- name: Check if build should be run | |||||
id: check-build | |||||
run: | | |||||
python "${GITHUB_WORKSPACE}/.github/helper/roulette.py" | |||||
env: | |||||
TYPE: "server" | |||||
PR_NUMBER: ${{ github.event.number }} | |||||
REPO_NAME: ${{ github.repository }} | |||||
- uses: actions/setup-node@v2 | - uses: actions/setup-node@v2 | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
with: | with: | ||||
node-version: '14' | node-version: '14' | ||||
check-latest: true | check-latest: true | ||||
- name: Add to Hosts | - name: Add to Hosts | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: | | run: | | ||||
echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | ||||
echo "127.0.0.1 test_site_producer" | sudo tee -a /etc/hosts | echo "127.0.0.1 test_site_producer" | sudo tee -a /etc/hosts | ||||
- name: Cache pip | - name: Cache pip | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
with: | with: | ||||
path: ~/.cache/pip | path: ~/.cache/pip | ||||
@@ -57,6 +75,7 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Cache node modules | - name: Cache node modules | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
env: | env: | ||||
cache-name: cache-node-modules | cache-name: cache-node-modules | ||||
@@ -69,10 +88,12 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Get yarn cache directory path | - name: Get yarn cache directory path | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache-dir-path | id: yarn-cache-dir-path | ||||
run: echo "::set-output name=dir::$(yarn cache dir)" | run: echo "::set-output name=dir::$(yarn cache dir)" | ||||
- uses: actions/cache@v2 | - uses: actions/cache@v2 | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache | id: yarn-cache | ||||
with: | with: | ||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
@@ -81,6 +102,7 @@ jobs: | |||||
${{ runner.os }}-yarn- | ${{ runner.os }}-yarn- | ||||
- name: Install Dependencies | - name: Install Dependencies | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | ||||
env: | env: | ||||
BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | ||||
@@ -88,13 +110,23 @@ jobs: | |||||
TYPE: server | TYPE: server | ||||
- name: Install | - name: Install | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | ||||
env: | env: | ||||
DB: postgres | DB: postgres | ||||
TYPE: server | TYPE: server | ||||
- name: Run Tests | - name: Run Tests | ||||
run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --use-orchestrator | |||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --use-orchestrator --with-coverage | |||||
env: | env: | ||||
CI_BUILD_ID: ${{ github.run_id }} | CI_BUILD_ID: ${{ github.run_id }} | ||||
ORCHESTRATOR_URL: http://test-orchestrator.frappe.io | ORCHESTRATOR_URL: http://test-orchestrator.frappe.io | ||||
- name: Upload coverage data | |||||
uses: codecov/codecov-action@v2 | |||||
with: | |||||
name: Postgres | |||||
fail_ci_if_error: true | |||||
files: /home/runner/frappe-bench/sites/coverage.xml | |||||
verbose: true |
@@ -6,6 +6,10 @@ on: | |||||
push: | push: | ||||
branches: [ develop ] | branches: [ develop ] | ||||
concurrency: | |||||
group: ui-develop-${{ github.event.number }} | |||||
cancel-in-progress: true | |||||
jobs: | jobs: | ||||
test: | test: | ||||
runs-on: ubuntu-18.04 | runs-on: ubuntu-18.04 | ||||
@@ -35,17 +39,29 @@ jobs: | |||||
with: | with: | ||||
python-version: 3.7 | python-version: 3.7 | ||||
- name: Check if build should be run | |||||
id: check-build | |||||
run: | | |||||
python "${GITHUB_WORKSPACE}/.github/helper/roulette.py" | |||||
env: | |||||
TYPE: "ui" | |||||
PR_NUMBER: ${{ github.event.number }} | |||||
REPO_NAME: ${{ github.repository }} | |||||
- uses: actions/setup-node@v2 | - uses: actions/setup-node@v2 | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
with: | with: | ||||
node-version: 14 | node-version: 14 | ||||
check-latest: true | check-latest: true | ||||
- name: Add to Hosts | - name: Add to Hosts | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: | | run: | | ||||
echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts | ||||
echo "127.0.0.1 test_site_producer" | sudo tee -a /etc/hosts | echo "127.0.0.1 test_site_producer" | sudo tee -a /etc/hosts | ||||
- name: Cache pip | - name: Cache pip | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
with: | with: | ||||
path: ~/.cache/pip | path: ~/.cache/pip | ||||
@@ -55,6 +71,7 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Cache node modules | - name: Cache node modules | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
env: | env: | ||||
cache-name: cache-node-modules | cache-name: cache-node-modules | ||||
@@ -67,10 +84,12 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Get yarn cache directory path | - name: Get yarn cache directory path | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache-dir-path | id: yarn-cache-dir-path | ||||
run: echo "::set-output name=dir::$(yarn cache dir)" | run: echo "::set-output name=dir::$(yarn cache dir)" | ||||
- uses: actions/cache@v2 | - uses: actions/cache@v2 | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
id: yarn-cache | id: yarn-cache | ||||
with: | with: | ||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | ||||
@@ -79,6 +98,7 @@ jobs: | |||||
${{ runner.os }}-yarn- | ${{ runner.os }}-yarn- | ||||
- name: Cache cypress binary | - name: Cache cypress binary | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
uses: actions/cache@v2 | uses: actions/cache@v2 | ||||
with: | with: | ||||
path: ~/.cache | path: ~/.cache | ||||
@@ -88,6 +108,7 @@ jobs: | |||||
${{ runner.os }}- | ${{ runner.os }}- | ||||
- name: Install Dependencies | - name: Install Dependencies | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh | ||||
env: | env: | ||||
BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} | ||||
@@ -95,15 +116,18 @@ jobs: | |||||
TYPE: ui | TYPE: ui | ||||
- name: Install | - name: Install | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh | ||||
env: | env: | ||||
DB: mariadb | DB: mariadb | ||||
TYPE: ui | TYPE: ui | ||||
- name: Site Setup | - name: Site Setup | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: cd ~/frappe-bench/ && bench --site test_site execute frappe.utils.install.complete_setup_wizard | run: cd ~/frappe-bench/ && bench --site test_site execute frappe.utils.install.complete_setup_wizard | ||||
- name: UI Tests | - name: UI Tests | ||||
if: ${{ steps.check-build.outputs.build == 'strawberry' }} | |||||
run: cd ~/frappe-bench/ && bench --site test_site run-ui-tests frappe --headless --parallel --ci-build-id $GITHUB_RUN_ID | run: cd ~/frappe-bench/ && bench --site test_site run-ui-tests frappe --headless --parallel --ci-build-id $GITHUB_RUN_ID | ||||
env: | env: | ||||
CYPRESS_RECORD_KEY: 4a48f41c-11b3-425b-aa88-c58048fa69eb | CYPRESS_RECORD_KEY: 4a48f41c-11b3-425b-aa88-c58048fa69eb |
@@ -1,4 +1,20 @@ | |||||
pull_request_rules: | pull_request_rules: | ||||
- name: Auto-close PRs on stable branch | |||||
conditions: | |||||
- and: | |||||
- and: | |||||
- author!=surajshetty3416 | |||||
- author!=gavindsouza | |||||
- or: | |||||
- base=version-13 | |||||
- base=version-12 | |||||
actions: | |||||
close: | |||||
comment: | |||||
message: | | |||||
@{{author}}, thanks for the contribution, but we do not accept pull requests on a stable branch. Please raise PR on an appropriate hotfix branch. | |||||
https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist#which-branch | |||||
- name: Automatic merge on CI success and review | - name: Automatic merge on CI success and review | ||||
conditions: | conditions: | ||||
- status-success=Sider | - status-success=Sider | ||||
@@ -7,10 +7,13 @@ | |||||
templates/ @surajshetty3416 | templates/ @surajshetty3416 | ||||
www/ @surajshetty3416 | www/ @surajshetty3416 | ||||
integrations/ @leela | integrations/ @leela | ||||
patches/ @surajshetty3416 | |||||
patches/ @surajshetty3416 @gavindsouza | |||||
email/ @leela | email/ @leela | ||||
event_streaming/ @ruchamahabal | event_streaming/ @ruchamahabal | ||||
data_import* @netchampfaris | data_import* @netchampfaris | ||||
core/ @surajshetty3416 | core/ @surajshetty3416 | ||||
database @gavindsouza | |||||
model @gavindsouza | |||||
requirements.txt @gavindsouza | requirements.txt @gavindsouza | ||||
commands/ @gavindsouza | commands/ @gavindsouza | ||||
workspace @shariquerik |
@@ -1,6 +1,6 @@ | |||||
The MIT License | The MIT License | ||||
Copyright (c) 2016-2018 Frappe Technologies Pvt. Ltd. <developers@frappe.io> | |||||
Copyright (c) 2016-2021 Frappe Technologies Pvt. Ltd. <developers@frappe.io> | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
of this software and associated documentation files (the "Software"), to deal | of this software and associated documentation files (the "Software"), to deal | ||||
@@ -26,8 +26,8 @@ | |||||
<a href='https://www.codetriage.com/frappe/frappe'> | <a href='https://www.codetriage.com/frappe/frappe'> | ||||
<img src='https://www.codetriage.com/frappe/frappe/badges/users.svg'> | <img src='https://www.codetriage.com/frappe/frappe/badges/users.svg'> | ||||
</a> | </a> | ||||
<a href='https://coveralls.io/github/frappe/frappe?branch=develop'> | |||||
<img src='https://coveralls.io/repos/github/frappe/frappe/badge.svg?branch=develop'> | |||||
<a href="https://codecov.io/gh/frappe/frappe"> | |||||
<img src="https://codecov.io/gh/frappe/frappe/branch/develop/graph/badge.svg?token=XoTa679hIj"/> | |||||
</a> | </a> | ||||
</div> | </div> | ||||
@@ -0,0 +1,9 @@ | |||||
codecov: | |||||
require_ci_to_pass: yes | |||||
status: | |||||
project: | |||||
default: | |||||
threshold: 0.5% | |||||
comment: | |||||
layout: "diff, flags, files" | |||||
require_changes: true |
@@ -10,9 +10,9 @@ context('Awesome Bar', () => { | |||||
}); | }); | ||||
it('navigates to doctype list', () => { | it('navigates to doctype list', () => { | ||||
cy.get('#navbar-search').type('todo', { delay: 200 }); | |||||
cy.get('#navbar-search + ul').should('be.visible'); | |||||
cy.get('#navbar-search').type('{downarrow}{enter}', { delay: 100 }); | |||||
cy.findByPlaceholderText('Search or type a command (Ctrl + G)').type('todo', { delay: 200 }); | |||||
cy.get('.awesomplete').findByRole('listbox').should('be.visible'); | |||||
cy.findByPlaceholderText('Search or type a command (Ctrl + G)').type('{downarrow}{enter}', { delay: 100 }); | |||||
cy.get('.title-text').should('contain', 'To Do'); | cy.get('.title-text').should('contain', 'To Do'); | ||||
@@ -20,24 +20,24 @@ context('Awesome Bar', () => { | |||||
}); | }); | ||||
it('find text in doctype list', () => { | it('find text in doctype list', () => { | ||||
cy.get('#navbar-search') | |||||
cy.findByPlaceholderText('Search or type a command (Ctrl + G)') | |||||
.type('test in todo{downarrow}{enter}', { delay: 200 }); | .type('test in todo{downarrow}{enter}', { delay: 200 }); | ||||
cy.get('.title-text').should('contain', 'To Do'); | cy.get('.title-text').should('contain', 'To Do'); | ||||
cy.get('[data-original-title="Name"] > .input-with-feedback') | |||||
cy.findByPlaceholderText('Name') | |||||
.should('have.value', '%test%'); | .should('have.value', '%test%'); | ||||
}); | }); | ||||
it('navigates to new form', () => { | it('navigates to new form', () => { | ||||
cy.get('#navbar-search') | |||||
cy.findByPlaceholderText('Search or type a command (Ctrl + G)') | |||||
.type('new blog post{downarrow}{enter}', { delay: 200 }); | .type('new blog post{downarrow}{enter}', { delay: 200 }); | ||||
cy.get('.title-text:visible').should('have.text', 'New Blog Post'); | cy.get('.title-text:visible').should('have.text', 'New Blog Post'); | ||||
}); | }); | ||||
it('calculates math expressions', () => { | it('calculates math expressions', () => { | ||||
cy.get('#navbar-search') | |||||
cy.findByPlaceholderText('Search or type a command (Ctrl + G)') | |||||
.type('55 + 32{downarrow}{enter}', { delay: 200 }); | .type('55 + 32{downarrow}{enter}', { delay: 200 }); | ||||
cy.get('.modal-title').should('contain', 'Result'); | cy.get('.modal-title').should('contain', 'Result'); | ||||
@@ -20,7 +20,7 @@ context('Control Barcode', () => { | |||||
it('should generate barcode on setting a value', () => { | it('should generate barcode on setting a value', () => { | ||||
get_dialog_with_barcode().as('dialog'); | get_dialog_with_barcode().as('dialog'); | ||||
cy.get('.frappe-control[data-fieldname=barcode] input') | |||||
cy.get('.frappe-control[data-fieldname=barcode]').findByRole('textbox') | |||||
.focus() | .focus() | ||||
.type('123456789') | .type('123456789') | ||||
.blur(); | .blur(); | ||||
@@ -37,11 +37,11 @@ context('Control Barcode', () => { | |||||
it('should reset when input is cleared', () => { | it('should reset when input is cleared', () => { | ||||
get_dialog_with_barcode().as('dialog'); | get_dialog_with_barcode().as('dialog'); | ||||
cy.get('.frappe-control[data-fieldname=barcode] input') | |||||
cy.get('.frappe-control[data-fieldname=barcode]').findByRole('textbox') | |||||
.focus() | .focus() | ||||
.type('123456789') | .type('123456789') | ||||
.blur(); | .blur(); | ||||
cy.get('.frappe-control[data-fieldname=barcode] input') | |||||
cy.get('.frappe-control[data-fieldname=barcode]').findByRole('textbox') | |||||
.clear() | .clear() | ||||
.blur(); | .blur(); | ||||
cy.get('.frappe-control[data-fieldname=barcode] svg[data-barcode-value="123456789"]') | cy.get('.frappe-control[data-fieldname=barcode] svg[data-barcode-value="123456789"]') | ||||
@@ -17,17 +17,17 @@ context('Control Icon', () => { | |||||
it('should set icon', () => { | it('should set icon', () => { | ||||
get_dialog_with_icon().as('dialog'); | get_dialog_with_icon().as('dialog'); | ||||
cy.get('.frappe-control[data-fieldname=icon] input').first().click(); | |||||
cy.get('.frappe-control[data-fieldname=icon]').findByRole('textbox').click(); | |||||
cy.get('.icon-picker .icon-wrapper[id=active]').first().click(); | cy.get('.icon-picker .icon-wrapper[id=active]').first().click(); | ||||
cy.get('.frappe-control[data-fieldname=icon] input').first().should('have.value', 'active'); | |||||
cy.get('.frappe-control[data-fieldname=icon]').findByRole('textbox').should('have.value', 'active'); | |||||
cy.get('@dialog').then(dialog => { | cy.get('@dialog').then(dialog => { | ||||
let value = dialog.get_value('icon'); | let value = dialog.get_value('icon'); | ||||
expect(value).to.equal('active'); | expect(value).to.equal('active'); | ||||
}); | }); | ||||
cy.get('.icon-picker .icon-wrapper[id=resting]').first().click(); | cy.get('.icon-picker .icon-wrapper[id=resting]').first().click(); | ||||
cy.get('.frappe-control[data-fieldname=icon] input').first().should('have.value', 'resting'); | |||||
cy.get('.frappe-control[data-fieldname=icon]').findByRole('textbox').should('have.value', 'resting'); | |||||
cy.get('@dialog').then(dialog => { | cy.get('@dialog').then(dialog => { | ||||
let value = dialog.get_value('icon'); | let value = dialog.get_value('icon'); | ||||
expect(value).to.equal('resting'); | expect(value).to.equal('resting'); | ||||
@@ -36,14 +36,14 @@ context('Control Icon', () => { | |||||
it('search for icon and clear search input', () => { | it('search for icon and clear search input', () => { | ||||
let search_text = 'ed'; | let search_text = 'ed'; | ||||
cy.get('.icon-picker input[type=search]').first().click().type(search_text); | |||||
cy.get('.icon-picker').findByRole('searchbox').click().type(search_text); | |||||
cy.get('.icon-section .icon-wrapper:not(.hidden)').then(i => { | cy.get('.icon-section .icon-wrapper:not(.hidden)').then(i => { | ||||
cy.get(`.icon-section .icon-wrapper[id*='${search_text}']`).then(icons => { | cy.get(`.icon-section .icon-wrapper[id*='${search_text}']`).then(icons => { | ||||
expect(i.length).to.equal(icons.length); | expect(i.length).to.equal(icons.length); | ||||
}); | }); | ||||
}); | }); | ||||
cy.get('.icon-picker input[type=search]').clear().blur(); | |||||
cy.get('.icon-picker').findByRole('searchbox').clear().blur(); | |||||
cy.get('.icon-section .icon-wrapper').should('not.have.class', 'hidden'); | cy.get('.icon-section .icon-wrapper').should('not.have.class', 'hidden'); | ||||
}); | }); | ||||
@@ -35,7 +35,7 @@ context('Control Link', () => { | |||||
cy.wait('@search_link'); | cy.wait('@search_link'); | ||||
cy.get('@input').type('todo for link', { delay: 200 }); | cy.get('@input').type('todo for link', { delay: 200 }); | ||||
cy.wait('@search_link'); | cy.wait('@search_link'); | ||||
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible'); | |||||
cy.get('.frappe-control[data-fieldname=link]').findByRole('listbox').should('be.visible'); | |||||
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 }); | cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 }); | ||||
cy.get('.frappe-control[data-fieldname=link] input').blur(); | cy.get('.frappe-control[data-fieldname=link] input').blur(); | ||||
cy.get('@dialog').then(dialog => { | cy.get('@dialog').then(dialog => { | ||||
@@ -71,7 +71,7 @@ context('Control Link', () => { | |||||
cy.get('@input').type(todos[0]).blur(); | cy.get('@input').type(todos[0]).blur(); | ||||
cy.wait('@validate_link'); | cy.wait('@validate_link'); | ||||
cy.get('@input').focus(); | cy.get('@input').focus(); | ||||
cy.get('.frappe-control[data-fieldname=link] .link-btn') | |||||
cy.findByTitle('Open Link') | |||||
.should('be.visible') | .should('be.visible') | ||||
.click(); | .click(); | ||||
cy.location('pathname').should('eq', `/app/todo/${todos[0]}`); | cy.location('pathname').should('eq', `/app/todo/${todos[0]}`); | ||||
@@ -24,8 +24,10 @@ context('Control Select', () => { | |||||
cy.get('@control').get('.select-icon').should('exist'); | cy.get('@control').get('.select-icon').should('exist'); | ||||
cy.get('@control').get('.placeholder').should('have.css', 'display', 'block'); | cy.get('@control').get('.placeholder').should('have.css', 'display', 'block'); | ||||
cy.get('@select').select('Option 1'); | cy.get('@select').select('Option 1'); | ||||
cy.findByDisplayValue('Option 1').should('exist'); | |||||
cy.get('@control').get('.placeholder').should('have.css', 'display', 'none'); | cy.get('@control').get('.placeholder').should('have.css', 'display', 'none'); | ||||
cy.get('@select').invoke('val', ''); | cy.get('@select').invoke('val', ''); | ||||
cy.findByDisplayValue('Option 1').should('not.exist'); | |||||
cy.get('@control').get('.placeholder').should('have.css', 'display', 'block'); | cy.get('@control').get('.placeholder').should('have.css', 'display', 'block'); | ||||
@@ -0,0 +1,63 @@ | |||||
context('Dashboard links', () => { | |||||
before(() => { | |||||
cy.visit('/login'); | |||||
cy.login(); | |||||
}); | |||||
it('Adding a new contact, checking for the counter on the dashboard and deleting the created contact', () => { | |||||
cy.visit('/app/contact'); | |||||
cy.clear_filters(); | |||||
cy.visit('/app/user'); | |||||
cy.get('.list-row-col > .level-item > .ellipsis').eq(0).click(); | |||||
//To check if initially the dashboard contains only the "Contact" link and there is no counter | |||||
cy.get('[data-doctype="Contact"]').should('contain', 'Contact'); | |||||
//Adding a new contact | |||||
cy.get('.btn[data-doctype="Contact"]').click(); | |||||
cy.get('[data-doctype="Contact"][data-fieldname="first_name"]').type('Admin'); | |||||
cy.findByRole('button', {name: 'Save'}).click(); | |||||
cy.visit('/app/user'); | |||||
cy.get('.list-row-col > .level-item > .ellipsis').eq(0).click(); | |||||
//To check if the counter for contact doc is "1" after adding the contact | |||||
cy.get('[data-doctype="Contact"] > .count').should('contain', '1'); | |||||
cy.get('[data-doctype="Contact"]').contains('Contact').click(); | |||||
//Deleting the newly created contact | |||||
cy.visit('/app/contact'); | |||||
cy.get('.list-subject > .select-like > .list-row-checkbox').eq(0).click(); | |||||
cy.findByRole('button', {name: 'Actions'}).click(); | |||||
cy.get('.actions-btn-group [data-label="Delete"]').click(); | |||||
cy.findByRole('button', {name: 'Yes'}).click({delay: 700}); | |||||
//To check if the counter from the "Contact" doc link is removed | |||||
cy.wait(700); | |||||
cy.visit('/app/user'); | |||||
cy.get('.list-row-col > .level-item > .ellipsis').eq(0).click(); | |||||
cy.get('[data-doctype="Contact"]').should('contain', 'Contact'); | |||||
}); | |||||
it('Report link in dashboard', () => { | |||||
cy.visit('/app/user'); | |||||
cy.visit('/app/user/Administrator'); | |||||
cy.get('[data-doctype="Contact"]').should('contain', 'Contact'); | |||||
cy.findByText('Connections'); | |||||
cy.window() | |||||
.its('cur_frm') | |||||
.then(cur_frm => { | |||||
cur_frm.dashboard.data.reports = [ | |||||
{ | |||||
'label': 'Reports', | |||||
'items': ['Permitted Documents For User'] | |||||
} | |||||
]; | |||||
cur_frm.dashboard.render_report_links(); | |||||
cy.get('[data-report="Permitted Documents For User"]').contains('Permitted Documents For User').click(); | |||||
cy.findByText('Permitted Documents For User'); | |||||
cy.findByPlaceholderText('User').should("have.value", "Administrator"); | |||||
}); | |||||
}); | |||||
}); |
@@ -0,0 +1,19 @@ | |||||
context('Datetime Field Validation', () => { | |||||
before(() => { | |||||
cy.login(); | |||||
cy.visit('/app/communication'); | |||||
cy.window().its('frappe').then(frappe => { | |||||
frappe.call("frappe.tests.ui_test_helpers.create_communication_records"); | |||||
}); | |||||
}); | |||||
// validating datetime field value when value is set from backend and get validated on form load. | |||||
it('datetime field form validation', () => { | |||||
cy.visit('/app/communication'); | |||||
cy.get('a[title="Test Form Communication 1"]').invoke('attr', 'data-name') | |||||
.then((name) => { | |||||
cy.visit(`/app/communication/${name}`); | |||||
cy.get('.indicator-pill').should('contain', 'Open').should('have.class', 'red'); | |||||
}); | |||||
}); | |||||
}); |
@@ -62,11 +62,11 @@ context('Depends On', () => { | |||||
it('should set the field as mandatory depending on other fields value', () => { | it('should set the field as mandatory depending on other fields value', () => { | ||||
cy.new_form('Test Depends On'); | cy.new_form('Test Depends On'); | ||||
cy.fill_field('test_field', 'Some Value'); | cy.fill_field('test_field', 'Some Value'); | ||||
cy.get('button.primary-action').contains('Save').click(); | |||||
cy.findByRole('button', {name: 'Save'}).click(); | |||||
cy.get('.msgprint-dialog .modal-title').contains('Missing Fields').should('be.visible'); | cy.get('.msgprint-dialog .modal-title').contains('Missing Fields').should('be.visible'); | ||||
cy.hide_dialog(); | cy.hide_dialog(); | ||||
cy.fill_field('test_field', 'Random value'); | cy.fill_field('test_field', 'Random value'); | ||||
cy.get('button.primary-action').contains('Save').click(); | |||||
cy.findByRole('button', {name: 'Save'}).click(); | |||||
cy.get('.msgprint-dialog .modal-title').contains('Missing Fields').should('not.be.visible'); | cy.get('.msgprint-dialog .modal-title').contains('Missing Fields').should('not.be.visible'); | ||||
}); | }); | ||||
it('should set the field as read only depending on other fields value', () => { | it('should set the field as read only depending on other fields value', () => { | ||||
@@ -84,7 +84,7 @@ context('Depends On', () => { | |||||
cy.fill_field('dependant_field', 'Some Value'); | cy.fill_field('dependant_field', 'Some Value'); | ||||
//cy.fill_field('test_field', 'Some Other Value'); | //cy.fill_field('test_field', 'Some Other Value'); | ||||
cy.get('.frappe-control[data-fieldname="child_test_depends_on_field"]').as('table'); | cy.get('.frappe-control[data-fieldname="child_test_depends_on_field"]').as('table'); | ||||
cy.get('@table').find('button.grid-add-row').click(); | |||||
cy.get('@table').findByRole('button', {name: 'Add Row'}).click(); | |||||
cy.get('@table').find('[data-idx="1"]').as('row1'); | cy.get('@table').find('[data-idx="1"]').as('row1'); | ||||
cy.get('@row1').find('.btn-open-row').click(); | cy.get('@row1').find('.btn-open-row').click(); | ||||
cy.get('@row1').find('.form-in-grid').as('row1-form_in_grid'); | cy.get('@row1').find('.form-in-grid').as('row1-form_in_grid'); | ||||
@@ -25,7 +25,7 @@ context('FileUploader', () => { | |||||
cy.get_open_dialog().find('.file-name').should('contain', 'example.json'); | cy.get_open_dialog().find('.file-name').should('contain', 'example.json'); | ||||
cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | ||||
cy.get_open_dialog().find('.btn-modal-primary').click(); | |||||
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click(); | |||||
cy.wait('@upload_file').its('response.statusCode').should('eq', 200); | cy.wait('@upload_file').its('response.statusCode').should('eq', 200); | ||||
cy.get('.modal:visible').should('not.exist'); | cy.get('.modal:visible').should('not.exist'); | ||||
}); | }); | ||||
@@ -33,11 +33,11 @@ context('FileUploader', () => { | |||||
it('should accept uploaded files', () => { | it('should accept uploaded files', () => { | ||||
open_upload_dialog(); | open_upload_dialog(); | ||||
cy.get_open_dialog().find('.btn-file-upload div:contains("Library")').click(); | |||||
cy.get('.file-filter').type('example.json'); | |||||
cy.get_open_dialog().find('.tree-label:contains("example.json")').first().click(); | |||||
cy.get_open_dialog().findByRole('button', {name: 'Library'}).click(); | |||||
cy.findByPlaceholderText('Search by filename or extension').type('example.json'); | |||||
cy.get_open_dialog().findAllByText('example.json').first().click(); | |||||
cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | ||||
cy.get_open_dialog().find('.btn-primary').click(); | |||||
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click(); | |||||
cy.wait('@upload_file').its('response.body.message') | cy.wait('@upload_file').its('response.body.message') | ||||
.should('have.property', 'file_name', 'example.json'); | .should('have.property', 'file_name', 'example.json'); | ||||
cy.get('.modal:visible').should('not.exist'); | cy.get('.modal:visible').should('not.exist'); | ||||
@@ -46,10 +46,12 @@ context('FileUploader', () => { | |||||
it('should accept web links', () => { | it('should accept web links', () => { | ||||
open_upload_dialog(); | open_upload_dialog(); | ||||
cy.get_open_dialog().find('.btn-file-upload div:contains("Link")').click(); | |||||
cy.get_open_dialog().find('.file-web-link input').type('https://github.com', { delay: 100, force: true }); | |||||
cy.get_open_dialog().findByRole('button', {name: 'Link'}).click(); | |||||
cy.get_open_dialog() | |||||
.findByPlaceholderText('Attach a web link') | |||||
.type('https://github.com', { delay: 100, force: true }); | |||||
cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | ||||
cy.get_open_dialog().find('.btn-primary').click(); | |||||
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click(); | |||||
cy.wait('@upload_file').its('response.body.message') | cy.wait('@upload_file').its('response.body.message') | ||||
.should('have.property', 'file_url', 'https://github.com'); | .should('have.property', 'file_url', 'https://github.com'); | ||||
cy.get('.modal:visible').should('not.exist'); | cy.get('.modal:visible').should('not.exist'); | ||||
@@ -62,15 +64,14 @@ context('FileUploader', () => { | |||||
subjectType: 'drag-n-drop', | subjectType: 'drag-n-drop', | ||||
}); | }); | ||||
cy.get_open_dialog().find('.file-name').should('contain', 'sample_image.jpg'); | |||||
cy.get_open_dialog().findAllByText('sample_image.jpg').should('exist'); | |||||
cy.get_open_dialog().find('.btn-crop').first().click(); | cy.get_open_dialog().find('.btn-crop').first().click(); | ||||
cy.get_open_dialog().find('.image-cropper-actions > .btn-primary').should('contain', 'Crop'); | |||||
cy.get_open_dialog().find('.image-cropper-actions > .btn-primary').click(); | |||||
cy.get_open_dialog().find('.optimize-checkbox').first().should('contain', 'Optimize'); | |||||
cy.get_open_dialog().find('.optimize-checkbox').first().click(); | |||||
cy.get_open_dialog().findByRole('button', {name: 'Crop'}).click(); | |||||
cy.get_open_dialog().findAllByRole('checkbox', {name: 'Optimize'}).should('exist'); | |||||
cy.get_open_dialog().findAllByLabelText('Optimize').first().click(); | |||||
cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | cy.intercept('POST', '/api/method/upload_file').as('upload_file'); | ||||
cy.get_open_dialog().find('.btn-modal-primary').click(); | |||||
cy.get_open_dialog().findByRole('button', {name: 'Upload'}).click(); | |||||
cy.wait('@upload_file').its('response.statusCode').should('eq', 200); | cy.wait('@upload_file').its('response.statusCode').should('eq', 200); | ||||
cy.get('.modal:visible').should('not.exist'); | cy.get('.modal:visible').should('not.exist'); | ||||
}); | }); | ||||
@@ -0,0 +1,79 @@ | |||||
context('Folder Navigation', () => { | |||||
before(() => { | |||||
cy.visit('/login'); | |||||
cy.login(); | |||||
cy.visit('/app/file'); | |||||
}); | |||||
it('Adding Folders', () => { | |||||
//Adding filter to go into the home folder | |||||
cy.get('.filter-selector > .btn').findByText('1 filter').click(); | |||||
cy.findByRole('button', {name: 'Clear Filters'}).click(); | |||||
cy.get('.filter-action-buttons > .text-muted').findByText('+ Add a Filter').click(); | |||||
cy.get('.fieldname-select-area > .awesomplete > .form-control').type('Fol{enter}'); | |||||
cy.get('.filter-field > .form-group > .link-field > .awesomplete > .input-with-feedback').type('Home{enter}'); | |||||
cy.get('.filter-action-buttons > div > .btn-primary').findByText('Apply Filters').click(); | |||||
//Adding folder (Test Folder) | |||||
cy.get('.menu-btn-group > .btn').click(); | |||||
cy.get('.menu-btn-group [data-label="New Folder"]').click(); | |||||
cy.get('form > [data-fieldname="value"]').type('Test Folder'); | |||||
cy.findByRole('button', {name: 'Create'}).click(); | |||||
}); | |||||
it('Navigating the nested folders, checking if the URL formed is correct, checking if the added content in the child folder is correct', () => { | |||||
//Navigating inside the Attachments folder | |||||
cy.get('[title="Attachments"] > span').click(); | |||||
//To check if the URL formed after visiting the attachments folder is correct | |||||
cy.location('pathname').should('eq', '/app/file/view/home/Attachments'); | |||||
cy.visit('/app/file/view/home/Attachments'); | |||||
//Adding folder inside the attachments folder | |||||
cy.get('.menu-btn-group > .btn').click(); | |||||
cy.get('.menu-btn-group [data-label="New Folder"]').click(); | |||||
cy.get('form > [data-fieldname="value"]').type('Test Folder'); | |||||
cy.findByRole('button', {name: 'Create'}).click(); | |||||
//Navigating inside the added folder in the Attachments folder | |||||
cy.get('[title="Test Folder"] > span').click(); | |||||
//To check if the URL is correct after visiting the Test Folder | |||||
cy.location('pathname').should('eq', '/app/file/view/home/Attachments/Test%20Folder'); | |||||
cy.visit('/app/file/view/home/Attachments/Test%20Folder'); | |||||
//Adding a file inside the Test Folder | |||||
cy.findByRole('button', {name: 'Add File'}).eq(0).click({force: true}); | |||||
cy.get('.file-uploader').findByText('Link').click(); | |||||
cy.get('.input-group > .form-control').type('https://wallpaperplay.com/walls/full/8/2/b/72402.jpg'); | |||||
cy.findByRole('button', {name: 'Upload'}).click(); | |||||
//To check if the added file is present in the Test Folder | |||||
cy.get('span.level-item > span').should('contain', 'Test Folder'); | |||||
cy.get('.list-row-container').eq(0).should('contain.text', '72402.jpg'); | |||||
cy.get('.list-row-checkbox').eq(0).click(); | |||||
//Deleting the added file from the Test folder | |||||
cy.findByRole('button', {name: 'Actions'}).click(); | |||||
cy.get('.actions-btn-group [data-label="Delete"]').click(); | |||||
cy.wait(700); | |||||
cy.findByRole('button', {name: 'Yes'}).click(); | |||||
cy.wait(700); | |||||
//Deleting the Test Folder | |||||
cy.visit('/app/file/view/home/Attachments'); | |||||
cy.get('.list-row-checkbox').eq(0).click(); | |||||
cy.findByRole('button', {name: 'Actions'}).click(); | |||||
cy.get('.actions-btn-group [data-label="Delete"]').click(); | |||||
cy.findByRole('button', {name: 'Yes'}).click(); | |||||
}); | |||||
it('Deleting Test Folder from the home', () => { | |||||
//Deleting the Test Folder added in the home directory | |||||
cy.visit('/app/file/view/home'); | |||||
cy.get('.level-left > .list-subject > .list-row-checkbox').eq(0).click({force: true, delay: 500}); | |||||
cy.findByRole('button', {name: 'Actions'}).click(); | |||||
cy.get('.actions-btn-group [data-label="Delete"]').click(); | |||||
cy.findByRole('button', {name: 'Yes'}).click(); | |||||
}); | |||||
}); |
@@ -26,7 +26,7 @@ context('Form', () => { | |||||
cy.visit('/app/contact'); | cy.visit('/app/contact'); | ||||
cy.add_filter(); | cy.add_filter(); | ||||
cy.get('.filter-field .input-with-feedback.form-control').type('123', { force: true }); | cy.get('.filter-field .input-with-feedback.form-control').type('123', { force: true }); | ||||
cy.get('.filter-popover .apply-filters').click({ force: true }); | |||||
cy.findByRole('button', {name: 'Apply Filters'}).click({ force: true }); | |||||
cy.visit('/app/contact/Test Form Contact 3'); | cy.visit('/app/contact/Test Form Contact 3'); | ||||
cy.get('.prev-doc').should('be.visible').click(); | cy.get('.prev-doc').should('be.visible').click(); | ||||
cy.get('.msgprint-dialog .modal-body').contains('No further records').should('be.visible'); | cy.get('.msgprint-dialog .modal-body').contains('No further records').should('be.visible'); | ||||
@@ -9,7 +9,7 @@ context('Form Tour', () => { | |||||
const open_test_form_tour = () => { | const open_test_form_tour = () => { | ||||
cy.visit('/app/form-tour/Test Form Tour'); | cy.visit('/app/form-tour/Test Form Tour'); | ||||
cy.get('button[data-label="Show%20Tour"]').should('be.visible').and('contain', 'Show Tour').as('show_tour'); | |||||
cy.findByRole('button', {name: 'Show Tour'}).should('be.visible').as('show_tour'); | |||||
cy.get('@show_tour').click(); | cy.get('@show_tour').click(); | ||||
cy.wait(500); | cy.wait(500); | ||||
cy.url().should('include', '/app/contact'); | cy.url().should('include', '/app/contact'); | ||||
@@ -20,10 +20,10 @@ context('Form Tour', () => { | |||||
it('navigates a form tour', () => { | it('navigates a form tour', () => { | ||||
open_test_form_tour(); | open_test_form_tour(); | ||||
cy.get('#driver-popover-item').should('be.visible'); | |||||
cy.get('.frappe-driver').should('be.visible'); | |||||
cy.get('.frappe-control[data-fieldname="first_name"]').as('first_name'); | cy.get('.frappe-control[data-fieldname="first_name"]').as('first_name'); | ||||
cy.get('@first_name').should('have.class', 'driver-highlighted-element'); | cy.get('@first_name').should('have.class', 'driver-highlighted-element'); | ||||
cy.get('.driver-next-btn').as('next_btn'); | |||||
cy.get('.frappe-driver').findByRole('button', {name: 'Next'}).as('next_btn'); | |||||
// next btn shouldn't move to next step, if first name is not entered | // next btn shouldn't move to next step, if first name is not entered | ||||
cy.get('@next_btn').click(); | cy.get('@next_btn').click(); | ||||
@@ -39,7 +39,7 @@ context('Form Tour', () => { | |||||
// assert field is highlighted | // assert field is highlighted | ||||
cy.get('.frappe-control[data-fieldname="last_name"]').as('last_name'); | cy.get('.frappe-control[data-fieldname="last_name"]').as('last_name'); | ||||
cy.get('@last_name').should('have.class', 'driver-highlighted-element'); | cy.get('@last_name').should('have.class', 'driver-highlighted-element'); | ||||
// after filling the field, next step should be highlighted | // after filling the field, next step should be highlighted | ||||
cy.fill_field('last_name', 'Test Last Name', 'Data'); | cy.fill_field('last_name', 'Test Last Name', 'Data'); | ||||
cy.wait(500); | cy.wait(500); | ||||
@@ -49,12 +49,12 @@ context('Form Tour', () => { | |||||
// assert field is highlighted | // assert field is highlighted | ||||
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('phone_nos'); | cy.get('.frappe-control[data-fieldname="phone_nos"]').as('phone_nos'); | ||||
cy.get('@phone_nos').should('have.class', 'driver-highlighted-element'); | cy.get('@phone_nos').should('have.class', 'driver-highlighted-element'); | ||||
// move to next step | // move to next step | ||||
cy.wait(500); | cy.wait(500); | ||||
cy.get('@next_btn').click(); | cy.get('@next_btn').click(); | ||||
cy.wait(500); | cy.wait(500); | ||||
// assert add row btn is highlighted | // assert add row btn is highlighted | ||||
cy.get('@phone_nos').find('.grid-add-row').as('add_row'); | cy.get('@phone_nos').find('.grid-add-row').as('add_row'); | ||||
cy.get('@add_row').should('have.class', 'driver-highlighted-element'); | cy.get('@add_row').should('have.class', 'driver-highlighted-element'); | ||||
@@ -68,21 +68,21 @@ context('Form Tour', () => { | |||||
cy.get('.grid-row-open .frappe-control[data-fieldname="phone"]').as('phone'); | cy.get('.grid-row-open .frappe-control[data-fieldname="phone"]').as('phone'); | ||||
cy.get('@phone').should('have.class', 'driver-highlighted-element'); | cy.get('@phone').should('have.class', 'driver-highlighted-element'); | ||||
// enter value in a table field | // enter value in a table field | ||||
cy.fill_table_field('phone_nos', '1', 'phone', '1234567890'); | |||||
let field = cy.fill_table_field('phone_nos', '1', 'phone', '1234567890'); | |||||
field.blur(); | |||||
// move to collapse row step | // move to collapse row step | ||||
cy.wait(500); | cy.wait(500); | ||||
cy.get('@next_btn').click(); | |||||
cy.get('.driver-popover-title').contains('Test Title 4').siblings().get('@next_btn').click(); | |||||
cy.wait(500); | cy.wait(500); | ||||
// collapse row | // collapse row | ||||
cy.get('.grid-row-open .grid-collapse-row').click(); | cy.get('.grid-row-open .grid-collapse-row').click(); | ||||
cy.wait(500); | cy.wait(500); | ||||
// assert save btn is highlighted | // assert save btn is highlighted | ||||
cy.get('.primary-action').should('have.class', 'driver-highlighted-element'); | cy.get('.primary-action').should('have.class', 'driver-highlighted-element'); | ||||
cy.get('@next_btn').should('contain', 'Save'); | |||||
cy.wait(500); | |||||
cy.get('.frappe-driver').findByRole('button', {name: 'Save'}).should('be.visible'); | |||||
}); | }); | ||||
}); | }); | ||||
@@ -30,12 +30,12 @@ context('Grid Pagination', () => { | |||||
it('adds and deletes rows and changes page', () => { | it('adds and deletes rows and changes page', () => { | ||||
cy.visit('/app/contact/Test Contact'); | cy.visit('/app/contact/Test Contact'); | ||||
cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table'); | cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table'); | ||||
cy.get('@table').find('button.grid-add-row').click(); | |||||
cy.get('@table').findByRole('button', {name: 'Add Row'}).click(); | |||||
cy.get('@table').find('.grid-body .row-index').should('contain', 1001); | cy.get('@table').find('.grid-body .row-index').should('contain', 1001); | ||||
cy.get('@table').find('.current-page-number').should('contain', '21'); | cy.get('@table').find('.current-page-number').should('contain', '21'); | ||||
cy.get('@table').find('.total-page-number').should('contain', '21'); | cy.get('@table').find('.total-page-number').should('contain', '21'); | ||||
cy.get('@table').find('.grid-body .grid-row .grid-row-check').click({ force: true }); | cy.get('@table').find('.grid-body .grid-row .grid-row-check').click({ force: true }); | ||||
cy.get('@table').find('button.grid-remove-rows').click(); | |||||
cy.get('@table').findByRole('button', {name: 'Delete'}).click(); | |||||
cy.get('@table').find('.grid-body .row-index').last().should('contain', 1000); | cy.get('@table').find('.grid-body .row-index').last().should('contain', 1000); | ||||
cy.get('@table').find('.current-page-number').should('contain', '20'); | cy.get('@table').find('.current-page-number').should('contain', '20'); | ||||
cy.get('@table').find('.total-page-number').should('contain', '20'); | cy.get('@table').find('.total-page-number').should('contain', '20'); | ||||
@@ -17,9 +17,9 @@ context('List View Settings', () => { | |||||
cy.get('.dropdown-menu li').filter(':visible').contains('List Settings').click(); | cy.get('.dropdown-menu li').filter(':visible').contains('List Settings').click(); | ||||
cy.get('.modal-dialog').should('contain', 'DocType Settings'); | cy.get('.modal-dialog').should('contain', 'DocType Settings'); | ||||
cy.get('input[data-fieldname="disable_count"]').check({ force: true }); | |||||
cy.get('input[data-fieldname="disable_sidebar_stats"]').check({ force: true }); | |||||
cy.get('button').filter(':visible').contains('Save').click(); | |||||
cy.findByLabelText('Disable Count').check({ force: true }); | |||||
cy.findByLabelText('Disable Sidebar Stats').check({ force: true }); | |||||
cy.findByRole('button', {name: 'Save'}).click(); | |||||
cy.reload({ force: true }); | cy.reload({ force: true }); | ||||
@@ -29,8 +29,8 @@ context('List View Settings', () => { | |||||
cy.get('.menu-btn-group button').click({ force: true }); | cy.get('.menu-btn-group button').click({ force: true }); | ||||
cy.get('.dropdown-menu li').filter(':visible').contains('List Settings').click(); | cy.get('.dropdown-menu li').filter(':visible').contains('List Settings').click(); | ||||
cy.get('.modal-dialog').should('contain', 'DocType Settings'); | cy.get('.modal-dialog').should('contain', 'DocType Settings'); | ||||
cy.get('input[data-fieldname="disable_count"]').uncheck({ force: true }); | |||||
cy.get('input[data-fieldname="disable_sidebar_stats"]').uncheck({ force: true }); | |||||
cy.get('button').filter(':visible').contains('Save').click(); | |||||
cy.findByLabelText('Disable Count').uncheck({ force: true }); | |||||
cy.findByLabelText('Disable Sidebar Stats').uncheck({ force: true }); | |||||
cy.findByRole('button', {name: 'Save'}).click(); | |||||
}); | }); | ||||
}); | }); |
@@ -11,13 +11,13 @@ context('Login', () => { | |||||
it('validates password', () => { | it('validates password', () => { | ||||
cy.get('#login_email').type('Administrator'); | cy.get('#login_email').type('Administrator'); | ||||
cy.get('.btn-login:visible').click(); | |||||
cy.findByRole('button', {name: 'Login'}).click(); | |||||
cy.location('pathname').should('eq', '/login'); | cy.location('pathname').should('eq', '/login'); | ||||
}); | }); | ||||
it('validates email', () => { | it('validates email', () => { | ||||
cy.get('#login_password').type('qwe'); | cy.get('#login_password').type('qwe'); | ||||
cy.get('.btn-login:visible').click(); | |||||
cy.findByRole('button', {name: 'Login'}).click(); | |||||
cy.location('pathname').should('eq', '/login'); | cy.location('pathname').should('eq', '/login'); | ||||
}); | }); | ||||
@@ -25,8 +25,8 @@ context('Login', () => { | |||||
cy.get('#login_email').type('Administrator'); | cy.get('#login_email').type('Administrator'); | ||||
cy.get('#login_password').type('qwer'); | cy.get('#login_password').type('qwer'); | ||||
cy.get('.btn-login:visible').click(); | |||||
cy.get('.btn-login:visible').contains('Invalid Login. Try again.'); | |||||
cy.findByRole('button', {name: 'Login'}).click(); | |||||
cy.findByRole('button', {name: 'Invalid Login. Try again.'}).should('exist'); | |||||
cy.location('pathname').should('eq', '/login'); | cy.location('pathname').should('eq', '/login'); | ||||
}); | }); | ||||
@@ -34,7 +34,7 @@ context('Login', () => { | |||||
cy.get('#login_email').type('Administrator'); | cy.get('#login_email').type('Administrator'); | ||||
cy.get('#login_password').type(Cypress.config('adminPassword')); | cy.get('#login_password').type(Cypress.config('adminPassword')); | ||||
cy.get('.btn-login:visible').click(); | |||||
cy.findByRole('button', {name: 'Login'}).click(); | |||||
cy.location('pathname').should('eq', '/app'); | cy.location('pathname').should('eq', '/app'); | ||||
cy.window().its('frappe.session.user').should('eq', 'Administrator'); | cy.window().its('frappe.session.user').should('eq', 'Administrator'); | ||||
}); | }); | ||||
@@ -60,7 +60,7 @@ context('Login', () => { | |||||
cy.get('#login_email').type('Administrator'); | cy.get('#login_email').type('Administrator'); | ||||
cy.get('#login_password').type(Cypress.config('adminPassword')); | cy.get('#login_password').type(Cypress.config('adminPassword')); | ||||
cy.get('.btn-login:visible').click(); | |||||
cy.findByRole('button', {name: 'Login'}).click(); | |||||
// verify redirected location and url params after login | // verify redirected location and url params after login | ||||
cy.url().should('include', '/me?' + payload.toString().replace('+', '%20')); | cy.url().should('include', '/me?' + payload.toString().replace('+', '%20')); | ||||
@@ -16,24 +16,24 @@ context('Recorder', () => { | |||||
it('Navigate to Recorder', () => { | it('Navigate to Recorder', () => { | ||||
cy.visit('/app'); | cy.visit('/app'); | ||||
cy.awesomebar('recorder'); | cy.awesomebar('recorder'); | ||||
cy.get('h3').should('contain', 'Recorder'); | |||||
cy.findByTitle('Recorder').should('exist'); | |||||
cy.url().should('include', '/recorder/detail'); | cy.url().should('include', '/recorder/detail'); | ||||
}); | }); | ||||
it('Recorder Empty State', () => { | it('Recorder Empty State', () => { | ||||
cy.get('.title-text').should('contain', 'Recorder'); | |||||
cy.findByTitle('Recorder').should('exist'); | |||||
cy.get('.indicator-pill').should('contain', 'Inactive').should('have.class', 'red'); | cy.get('.indicator-pill').should('contain', 'Inactive').should('have.class', 'red'); | ||||
cy.get('.primary-action').should('contain', 'Start'); | |||||
cy.get('.btn-secondary').should('contain', 'Clear'); | |||||
cy.findByRole('button', {name: 'Start'}).should('exist'); | |||||
cy.findByRole('button', {name: 'Clear'}).should('exist'); | |||||
cy.get('.msg-box').should('contain', 'Inactive'); | cy.get('.msg-box').should('contain', 'Inactive'); | ||||
cy.get('.msg-box .btn-primary').should('contain', 'Start Recording'); | |||||
cy.findByRole('button', {name: 'Start Recording'}).should('exist'); | |||||
}); | }); | ||||
it('Recorder Start', () => { | it('Recorder Start', () => { | ||||
cy.get('.primary-action').should('contain', 'Start').click(); | |||||
cy.findByRole('button', {name: 'Start'}).click(); | |||||
cy.get('.indicator-pill').should('contain', 'Active').should('have.class', 'green'); | cy.get('.indicator-pill').should('contain', 'Active').should('have.class', 'green'); | ||||
cy.get('.msg-box').should('contain', 'No Requests'); | cy.get('.msg-box').should('contain', 'No Requests'); | ||||
@@ -46,12 +46,12 @@ context('Recorder', () => { | |||||
cy.get('.list-count').should('contain', '20 of '); | cy.get('.list-count').should('contain', '20 of '); | ||||
cy.visit('/app/recorder'); | cy.visit('/app/recorder'); | ||||
cy.get('.title-text').should('contain', 'Recorder'); | |||||
cy.findByTitle('Recorder').should('exist'); | |||||
cy.get('.result-list').should('contain', '/api/method/frappe.desk.reportview.get'); | cy.get('.result-list').should('contain', '/api/method/frappe.desk.reportview.get'); | ||||
}); | }); | ||||
it('Recorder View Request', () => { | it('Recorder View Request', () => { | ||||
cy.get('.primary-action').should('contain', 'Start').click(); | |||||
cy.findByRole('button', {name: 'Start'}).click(); | |||||
cy.visit('/app/List/DocType/List'); | cy.visit('/app/List/DocType/List'); | ||||
cy.intercept('POST', '/api/method/frappe.desk.reportview.get').as('list_refresh'); | cy.intercept('POST', '/api/method/frappe.desk.reportview.get').as('list_refresh'); | ||||
@@ -23,7 +23,7 @@ context('Report View', () => { | |||||
let cell = cy.get('.dt-row-0 > .dt-cell--col-4'); | let cell = cy.get('.dt-row-0 > .dt-cell--col-4'); | ||||
// select the cell | // select the cell | ||||
cell.dblclick(); | cell.dblclick(); | ||||
cell.find('input[data-fieldname="enabled"]').check({ force: true }); | |||||
cell.findByRole('checkbox').check({ force: true }); | |||||
cy.get('.dt-row-0 > .dt-cell--col-5').click(); | cy.get('.dt-row-0 > .dt-cell--col-5').click(); | ||||
cy.wait('@value-update'); | cy.wait('@value-update'); | ||||
cy.get('@doc').then(doc => { | cy.get('@doc').then(doc => { | ||||
@@ -10,26 +10,26 @@ context('Timeline', () => { | |||||
it('Adding new ToDo, adding new comment, verifying comment addition & deletion and deleting ToDo', () => { | it('Adding new ToDo, adding new comment, verifying comment addition & deletion and deleting ToDo', () => { | ||||
//Adding new ToDo | //Adding new ToDo | ||||
cy.click_listview_primary_button('Add ToDo'); | cy.click_listview_primary_button('Add ToDo'); | ||||
cy.get('.modal-footer > .custom-actions > .btn').contains('Edit in full page').click(); | |||||
cy.get('.row > .section-body > .form-column > form > .frappe-control > .form-group > .control-input-wrapper > .control-input > .ql-container > .ql-editor').eq(0).type('Test ToDo', {force: true}); | |||||
cy.findByRole('button', {name: 'Edit in full page'}).click(); | |||||
cy.get('[data-fieldname="description"] .ql-editor').eq(0).type('Test ToDo', {force: true}); | |||||
cy.wait(200); | cy.wait(200); | ||||
cy.get('#page-ToDo > .page-head > .container > .row > .col > .standard-actions > .primary-action').contains('Save').click(); | |||||
cy.findByRole('button', {name: 'Save'}).click(); | |||||
cy.wait(700); | cy.wait(700); | ||||
cy.visit('/app/todo'); | cy.visit('/app/todo'); | ||||
cy.get('.list-row > .level-left > .list-subject > .level-item.ellipsis > .ellipsis').eq(0).click(); | |||||
cy.get('.level-item.ellipsis').eq(0).click(); | |||||
//To check if the comment box is initially empty and tying some text into it | //To check if the comment box is initially empty and tying some text into it | ||||
cy.get('.comment-input-container > .frappe-control > .ql-container > .ql-editor').should('contain', '').type('Testing Timeline'); | |||||
cy.get('[data-fieldname="comment"] .ql-editor').should('contain', '').type('Testing Timeline'); | |||||
//Adding new comment | //Adding new comment | ||||
cy.get('.comment-input-wrapper > .btn').contains('Comment').click(); | |||||
cy.findByRole('button', {name: 'Comment'}).click(); | |||||
//To check if the commented text is visible in the timeline content | //To check if the commented text is visible in the timeline content | ||||
cy.get('.timeline-content').should('contain', 'Testing Timeline'); | cy.get('.timeline-content').should('contain', 'Testing Timeline'); | ||||
//Editing comment | //Editing comment | ||||
cy.click_timeline_action_btn(0); | cy.click_timeline_action_btn(0); | ||||
cy.get('.timeline-content > .timeline-message-box > .comment-edit-box > .frappe-control > .ql-container > .ql-editor').first().type(' 123'); | |||||
cy.get('.timeline-content [data-fieldname="comment"] .ql-editor').first().type(' 123'); | |||||
cy.click_timeline_action_btn(0); | cy.click_timeline_action_btn(0); | ||||
//To check if the edited comment text is visible in timeline content | //To check if the edited comment text is visible in timeline content | ||||
@@ -37,20 +37,20 @@ context('Timeline', () => { | |||||
//Discarding comment | //Discarding comment | ||||
cy.click_timeline_action_btn(0); | cy.click_timeline_action_btn(0); | ||||
cy.get('.actions > .btn').eq(1).first().click(); | |||||
cy.findByRole('button', {name: 'Dismiss'}).click(); | |||||
//To check if after discarding the timeline content is same as previous | //To check if after discarding the timeline content is same as previous | ||||
cy.get('.timeline-content').should('contain', 'Testing Timeline 123'); | cy.get('.timeline-content').should('contain', 'Testing Timeline 123'); | ||||
//Deleting the added comment | //Deleting the added comment | ||||
cy.get('.actions > .btn > .icon').first().click(); | cy.get('.actions > .btn > .icon').first().click(); | ||||
cy.get('.modal-footer > .standard-actions > .btn-primary').contains('Yes').click(); | |||||
cy.findByRole('button', {name: 'Yes'}).click(); | |||||
cy.click_modal_primary_button('Yes'); | cy.click_modal_primary_button('Yes'); | ||||
//Deleting the added ToDo | //Deleting the added ToDo | ||||
cy.get('#page-ToDo > .page-head > .container > .row > .col > .standard-actions > .menu-btn-group > .btn').click({force: true}); | |||||
cy.get('.menu-btn-group > .dropdown-menu > li > .grey-link').eq(17).click({force: true}); | |||||
cy.get('.modal.show > .modal-dialog > .modal-content > .modal-footer > .standard-actions > .btn-primary').contains('Yes').click({force: true}); | |||||
cy.get('.menu-btn-group button').eq(1).click(); | |||||
cy.get('.menu-btn-group [data-label="Delete"]').click(); | |||||
cy.findByRole('button', {name: 'Yes'}).click(); | |||||
}); | }); | ||||
it('Timeline should have submit and cancel activity information', () => { | it('Timeline should have submit and cancel activity information', () => { | ||||
@@ -64,31 +64,31 @@ context('Timeline', () => { | |||||
//Adding a new entry for the created custom doctype | //Adding a new entry for the created custom doctype | ||||
cy.fill_field('title', 'Test'); | cy.fill_field('title', 'Test'); | ||||
cy.get('.modal-footer > .standard-actions > .btn-primary').contains('Save').click(); | |||||
cy.get('.modal-footer > .standard-actions > .btn-primary').contains('Submit').click(); | |||||
cy.findByRole('button', {name: 'Save'}).click(); | |||||
cy.findByRole('button', {name: 'Submit'}).click(); | |||||
cy.visit('/app/custom-submittable-doctype'); | cy.visit('/app/custom-submittable-doctype'); | ||||
cy.get('.list-subject > .bold > .ellipsis').eq(0).click(); | cy.get('.list-subject > .bold > .ellipsis').eq(0).click(); | ||||
//To check if the submission of the documemt is visible in the timeline content | //To check if the submission of the documemt is visible in the timeline content | ||||
cy.get('.timeline-content').should('contain', 'Administrator submitted this document'); | cy.get('.timeline-content').should('contain', 'Administrator submitted this document'); | ||||
cy.get('.page-actions > .standard-actions > .btn-secondary').contains('Cancel').click({delay: 900}); | |||||
cy.get('.modal-footer > .standard-actions > .btn-primary').contains('Yes').click(); | |||||
cy.findByRole('button', {name: 'Cancel'}).click({delay: 900}); | |||||
cy.findByRole('button', {name: 'Yes'}).click(); | |||||
//To check if the cancellation of the documemt is visible in the timeline content | //To check if the cancellation of the documemt is visible in the timeline content | ||||
cy.get('.timeline-content').should('contain', 'Administrator cancelled this document'); | cy.get('.timeline-content').should('contain', 'Administrator cancelled this document'); | ||||
//Deleting the document | //Deleting the document | ||||
cy.visit('/app/custom-submittable-doctype'); | cy.visit('/app/custom-submittable-doctype'); | ||||
cy.get('.list-subject > .select-like > .list-row-checkbox').eq(0).click(); | cy.get('.list-subject > .select-like > .list-row-checkbox').eq(0).click(); | ||||
cy.get('.page-actions > .standard-actions > .actions-btn-group > .btn').contains('Actions').click(); | |||||
cy.findByRole('button', {name: 'Actions'}).click(); | |||||
cy.get('.actions-btn-group > .dropdown-menu > li > .grey-link').eq(7).click(); | cy.get('.actions-btn-group > .dropdown-menu > li > .grey-link').eq(7).click(); | ||||
cy.click_modal_primary_button('Yes', {force: true, delay: 700}); | cy.click_modal_primary_button('Yes', {force: true, delay: 700}); | ||||
//Deleting the custom doctype | //Deleting the custom doctype | ||||
cy.visit('/app/doctype'); | cy.visit('/app/doctype'); | ||||
cy.get('.list-subject > .select-like > .list-row-checkbox').eq(0).click(); | cy.get('.list-subject > .select-like > .list-row-checkbox').eq(0).click(); | ||||
cy.get('.page-actions > .standard-actions > .actions-btn-group > .btn').contains('Actions').click(); | |||||
cy.get('.actions-btn-group > .dropdown-menu > li > .grey-link').eq(5).click(); | |||||
cy.findByRole('button', {name: 'Actions'}).click(); | |||||
cy.get('.actions-btn-group [data-label="Delete"]').click(); | |||||
cy.click_modal_primary_button('Yes'); | cy.click_modal_primary_button('Yes'); | ||||
}); | }); | ||||
}); | }); |
@@ -8,14 +8,13 @@ context('Timeline Email', () => { | |||||
it('Adding new ToDo, adding email and verifying timeline content for email attachment, deleting attachment and ToDo', () => { | it('Adding new ToDo, adding email and verifying timeline content for email attachment, deleting attachment and ToDo', () => { | ||||
//Adding new ToDo | //Adding new ToDo | ||||
cy.click_listview_primary_button('Add ToDo'); | cy.click_listview_primary_button('Add ToDo'); | ||||
cy.get('.custom-actions > .btn').trigger('click', {delay: 500}); | |||||
cy.get('.row > .section-body > .form-column > form > .frappe-control > .form-group > .control-input-wrapper > .control-input > .ql-container > .ql-editor').eq(0).type('Test ToDo', {force: true}); | |||||
cy.get('.custom-actions:visible > .btn').contains("Edit in full page").click({delay: 500}); | |||||
cy.fill_field("description", "Test ToDo", "Text Editor"); | |||||
cy.wait(500); | cy.wait(500); | ||||
//cy.click_listview_primary_button('Save'); | |||||
cy.get('.primary-action').contains('Save').click({force: true}); | cy.get('.primary-action').contains('Save').click({force: true}); | ||||
cy.wait(700); | cy.wait(700); | ||||
cy.visit('/app/todo'); | cy.visit('/app/todo'); | ||||
cy.get('.list-row > .level-left > .list-subject > .level-item.ellipsis > .ellipsis').eq(0).click(); | |||||
cy.get('.list-row > .level-left > .list-subject').eq(0).click(); | |||||
//Creating a new email | //Creating a new email | ||||
cy.get('.timeline-actions > .btn').click(); | cy.get('.timeline-actions > .btn').click(); | ||||
@@ -47,7 +46,7 @@ context('Timeline Email', () => { | |||||
//Removing the added attachment | //Removing the added attachment | ||||
cy.get('.attachment-row > .data-pill > .remove-btn > .icon').click(); | cy.get('.attachment-row > .data-pill > .remove-btn > .icon').click(); | ||||
cy.get('.modal-dialog > .modal-content > .modal-footer > .standard-actions > .btn-primary').contains('Yes').click(); | |||||
cy.get('.modal-footer:visible > .standard-actions > .btn-primary').contains('Yes').click(); | |||||
//To check if the removed attachment is shown in the timeline content | //To check if the removed attachment is shown in the timeline content | ||||
cy.get('.timeline-content').should('contain', 'Removed 72402.jpg'); | cy.get('.timeline-content').should('contain', 'Removed 72402.jpg'); | ||||
@@ -55,17 +54,17 @@ context('Timeline Email', () => { | |||||
//To check if the discard button functionality in email is working correctly | //To check if the discard button functionality in email is working correctly | ||||
cy.get('.timeline-actions > .btn').click(); | cy.get('.timeline-actions > .btn').click(); | ||||
cy.fill_field('recipients', 'test@example.com', 'MultiSelect'); | |||||
cy.fill_field('recipients', 'test@example.com', 'MultiSelect'); | |||||
cy.get('.modal-footer > .standard-actions > .btn-secondary').contains('Discard').click(); | cy.get('.modal-footer > .standard-actions > .btn-secondary').contains('Discard').click(); | ||||
cy.wait(500); | cy.wait(500); | ||||
cy.get('.timeline-actions > .btn').click(); | cy.get('.timeline-actions > .btn').click(); | ||||
cy.wait(500); | cy.wait(500); | ||||
cy.get_field('recipients', 'MultiSelect').should('have.text', ''); | cy.get_field('recipients', 'MultiSelect').should('have.text', ''); | ||||
cy.get('.modal.show > .modal-dialog > .modal-content > .modal-header > .modal-actions > .btn-modal-close > .icon').click(); | |||||
cy.get('.modal-header:visible > .modal-actions > .btn-modal-close > .icon').click(); | |||||
//Deleting the added ToDo | //Deleting the added ToDo | ||||
cy.get('#page-ToDo > .page-head > .container > .row > .col > .standard-actions > .menu-btn-group > .btn').click(); | |||||
cy.get('.menu-btn-group > .dropdown-menu > li > .grey-link').eq(17).click(); | |||||
cy.get('.modal.show > .modal-dialog > .modal-content > .modal-footer > .standard-actions > .btn-primary').click(); | |||||
cy.get('.menu-btn-group:visible > .btn').click(); | |||||
cy.get('.menu-btn-group:visible > .dropdown-menu > li > .dropdown-item').contains('Delete').click(); | |||||
cy.get('.modal-footer:visible > .standard-actions > .btn-primary').click(); | |||||
}); | }); | ||||
}); | }); |
@@ -0,0 +1,90 @@ | |||||
context('Workspace 2.0', () => { | |||||
before(() => { | |||||
cy.visit('/login'); | |||||
cy.login(); | |||||
cy.visit('/app/website'); | |||||
}); | |||||
it('Navigate to page from sidebar', () => { | |||||
cy.visit('/app/build'); | |||||
cy.get('.codex-editor__redactor .ce-block'); | |||||
cy.get('.sidebar-item-container[item-name="Settings"]').first().click(); | |||||
cy.location('pathname').should('eq', '/app/settings'); | |||||
}); | |||||
it('Create Private Page', () => { | |||||
cy.get('.codex-editor__redactor .ce-block'); | |||||
cy.get('.custom-actions button[data-label="Create%20Workspace"]').click(); | |||||
cy.fill_field('title', 'Test Private Page', 'Data'); | |||||
cy.fill_field('icon', 'edit', 'Icon'); | |||||
cy.get_open_dialog().find('.modal-header').click(); | |||||
cy.get_open_dialog().find('.btn-primary').click(); | |||||
// check if sidebar item is added in pubic section | |||||
cy.get('.sidebar-item-container[item-name="Test Private Page"]').should('have.attr', 'item-public', '0'); | |||||
cy.get('.standard-actions .btn-primary[data-label="Save Customizations"]').click(); | |||||
cy.wait(300); | |||||
cy.get('.sidebar-item-container[item-name="Test Private Page"]').should('have.attr', 'item-public', '0'); | |||||
cy.wait(500); | |||||
cy.get('.codex-editor__redactor .ce-block'); | |||||
cy.get('.standard-actions .btn-secondary[data-label=Edit]').click(); | |||||
}); | |||||
it('Add New Block', () => { | |||||
cy.get('.codex-editor__redactor .ce-block'); | |||||
cy.get('.custom-actions .inner-group-button[data-label="Add%20Block"]').click(); | |||||
cy.get('.custom-actions .inner-group-button .dropdown-menu .block-menu-item-label').contains('Heading').click(); | |||||
cy.get(":focus").type('Header'); | |||||
cy.get(".ce-block:last").find('.ce-header').should('exist'); | |||||
cy.get('.custom-actions .inner-group-button[data-label="Add%20Block"]').click(); | |||||
cy.get('.custom-actions .inner-group-button .dropdown-menu .block-menu-item-label').contains('Text').click(); | |||||
cy.get(":focus").type('Paragraph text'); | |||||
cy.get(".ce-block:last").find('.ce-paragraph').should('exist'); | |||||
}); | |||||
it('Delete A Block', () => { | |||||
cy.get(".ce-block:last").find('.delete-paragraph').click(); | |||||
cy.get(".ce-block:last").find('.ce-paragraph').should('not.exist'); | |||||
}); | |||||
it('Shrink and Expand A Block', () => { | |||||
cy.get(".ce-block:last").find('.tune-btn').click(); | |||||
cy.get('.ce-settings--opened .ce-shrink-button').click(); | |||||
cy.get(".ce-block:last").should('have.class', 'col-11'); | |||||
cy.get('.ce-settings--opened .ce-shrink-button').click(); | |||||
cy.get(".ce-block:last").should('have.class', 'col-10'); | |||||
cy.get('.ce-settings--opened .ce-shrink-button').click(); | |||||
cy.get(".ce-block:last").should('have.class', 'col-9'); | |||||
cy.get('.ce-settings--opened .ce-expand-button').click(); | |||||
cy.get(".ce-block:last").should('have.class', 'col-10'); | |||||
cy.get('.ce-settings--opened .ce-expand-button').click(); | |||||
cy.get(".ce-block:last").should('have.class', 'col-11'); | |||||
cy.get('.ce-settings--opened .ce-expand-button').click(); | |||||
cy.get(".ce-block:last").should('have.class', 'col-12'); | |||||
}); | |||||
it('Change Header Text Size', () => { | |||||
cy.get('.ce-settings--opened .cdx-settings-button[data-level="3"]').click(); | |||||
cy.get(".ce-block:last").find('.widget-head h3').should('exist'); | |||||
cy.get('.ce-settings--opened .cdx-settings-button[data-level="4"]').click(); | |||||
cy.get(".ce-block:last").find('.widget-head h4').should('exist'); | |||||
cy.get('.standard-actions .btn-primary[data-label="Save Customizations"]').click(); | |||||
}); | |||||
it('Delete Private Page', () => { | |||||
cy.get('.codex-editor__redactor .ce-block'); | |||||
cy.get('.standard-actions .btn-secondary[data-label=Edit]').click(); | |||||
cy.get('.sidebar-item-container[item-name="Test Private Page"]').find('.sidebar-item-control .delete-page').click(); | |||||
cy.wait(300); | |||||
cy.get('.modal-footer > .standard-actions > .btn-modal-primary:visible').first().click(); | |||||
cy.get('.standard-actions .btn-primary[data-label="Save Customizations"]').click(); | |||||
cy.get('.codex-editor__redactor .ce-block'); | |||||
cy.get('.sidebar-item-container[item-name="Test Private Page"]').should('not.exist'); | |||||
}); | |||||
}); |
@@ -1,4 +1,5 @@ | |||||
import 'cypress-file-upload'; | import 'cypress-file-upload'; | ||||
import '@testing-library/cypress/add-commands'; | |||||
// *********************************************** | // *********************************************** | ||||
// This example commands.js shows you how to | // This example commands.js shows you how to | ||||
// create various custom commands and overwrite | // create various custom commands and overwrite | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
""" | """ | ||||
Frappe - Low Code Open Source Framework in Python and JS | Frappe - Low Code Open Source Framework in Python and JS | ||||
@@ -140,7 +140,11 @@ lang = local("lang") | |||||
if typing.TYPE_CHECKING: | if typing.TYPE_CHECKING: | ||||
from frappe.database.mariadb.database import MariaDBDatabase | from frappe.database.mariadb.database import MariaDBDatabase | ||||
from frappe.database.postgres.database import PostgresDatabase | from frappe.database.postgres.database import PostgresDatabase | ||||
from pypika import Query | |||||
db: typing.Union[MariaDBDatabase, PostgresDatabase] | db: typing.Union[MariaDBDatabase, PostgresDatabase] | ||||
qb: Query | |||||
# end: static analysis hack | # end: static analysis hack | ||||
def init(site, sites_path=None, new_site=False): | def init(site, sites_path=None, new_site=False): | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import base64 | import base64 | ||||
import binascii | import binascii | ||||
import json | import json | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import os | import os | ||||
import logging | import logging | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and Contributors | # Copyright (c) 2019, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import unittest | import unittest | ||||
from frappe.utils import random_string | from frappe.utils import random_string | ||||
@@ -76,7 +76,7 @@ class TestAutoAssign(unittest.TestCase): | |||||
# clear 5 assignments for first user | # clear 5 assignments for first user | ||||
# can't do a limit in "delete" since postgres does not support it | # can't do a limit in "delete" since postgres does not support it | ||||
for d in frappe.get_all('ToDo', dict(reference_type = 'Note', owner = 'test@example.com'), limit=5): | for d in frappe.get_all('ToDo', dict(reference_type = 'Note', owner = 'test@example.com'), limit=5): | ||||
frappe.db.sql("delete from tabToDo where name = %s", d.name) | |||||
frappe.db.delete("ToDo", {"name": d.name}) | |||||
# add 5 more assignments | # add 5 more assignments | ||||
for i in range(5): | for i in range(5): | ||||
@@ -177,7 +177,7 @@ class TestAutoAssign(unittest.TestCase): | |||||
), 'owner'), 'test@example.com') | ), 'owner'), 'test@example.com') | ||||
def check_assignment_rule_scheduling(self): | def check_assignment_rule_scheduling(self): | ||||
frappe.db.sql("DELETE FROM `tabAssignment Rule`") | |||||
frappe.db.delete("Assignment Rule") | |||||
days_1 = [dict(day = 'Sunday'), dict(day = 'Monday'), dict(day = 'Tuesday')] | days_1 = [dict(day = 'Sunday'), dict(day = 'Monday'), dict(day = 'Tuesday')] | ||||
@@ -204,7 +204,7 @@ class TestAutoAssign(unittest.TestCase): | |||||
), 'owner'), ['test3@example.com']) | ), 'owner'), ['test3@example.com']) | ||||
def test_assignment_rule_condition(self): | def test_assignment_rule_condition(self): | ||||
frappe.db.sql("DELETE FROM `tabAssignment Rule`") | |||||
frappe.db.delete("Assignment Rule") | |||||
# Add expiry_date custom field | # Add expiry_date custom field | ||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field | from frappe.custom.doctype.custom_field.custom_field import create_custom_field | ||||
@@ -253,7 +253,7 @@ class TestAutoAssign(unittest.TestCase): | |||||
assignment_rule.delete() | assignment_rule.delete() | ||||
def clear_assignments(): | def clear_assignments(): | ||||
frappe.db.sql("delete from tabToDo where reference_type = 'Note'") | |||||
frappe.db.delete("ToDo", {"reference_type": "Note"}) | |||||
def get_assignment_rule(days, assign=None): | def get_assignment_rule(days, assign=None): | ||||
frappe.delete_doc_if_exists('Assignment Rule', 'For Note 1') | frappe.delete_doc_if_exists('Assignment Rule', 'For Note 1') | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
# import frappe | # import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
# import frappe | # import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -30,7 +30,7 @@ frappe.ui.form.on('Auto Repeat', { | |||||
refresh: function(frm) { | refresh: function(frm) { | ||||
// auto repeat message | // auto repeat message | ||||
if (frm.is_new()) { | if (frm.is_new()) { | ||||
let customize_form_link = `<a href="/app/customize form">${__('Customize Form')}</a>`; | |||||
let customize_form_link = `<a href="/app/customize-form">${__('Customize Form')}</a>`; | |||||
frm.dashboard.set_headline(__('To configure Auto Repeat, enable "Allow Auto Repeat" from {0}.', [customize_form_link])); | frm.dashboard.set_headline(__('To configure Auto Repeat, enable "Allow Auto Repeat" from {0}.', [customize_form_link])); | ||||
} | } | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors | # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2018, Frappe Technologies and Contributors | # Copyright (c) 2018, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import unittest | import unittest | ||||
import frappe | import frappe | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2020, Frappe Technologies and contributors | # Copyright (c) 2020, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
# import frappe | # import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and Contributors | # Copyright (c) 2019, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
#import frappe | #import frappe | ||||
import unittest | import unittest | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,13 +1,13 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and Contributors | # Copyright (c) 2019, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import frappe.cache_manager | import frappe.cache_manager | ||||
import unittest | import unittest | ||||
class TestMilestoneTracker(unittest.TestCase): | class TestMilestoneTracker(unittest.TestCase): | ||||
def test_milestone(self): | def test_milestone(self): | ||||
frappe.db.sql('delete from `tabMilestone Tracker`') | |||||
frappe.db.delete("Milestone Tracker") | |||||
frappe.cache().delete_key('milestone_tracker_map') | frappe.cache().delete_key('milestone_tracker_map') | ||||
@@ -44,5 +44,5 @@ class TestMilestoneTracker(unittest.TestCase): | |||||
self.assertEqual(milestones[0].value, 'Closed') | self.assertEqual(milestones[0].value, 'Closed') | ||||
# cleanup | # cleanup | ||||
frappe.db.sql('delete from tabMilestone') | |||||
frappe.db.delete("Milestone") | |||||
milestone_tracker.delete() | milestone_tracker.delete() |
@@ -1,22 +1,27 @@ | |||||
{ | { | ||||
"category": "Administration", | |||||
"category": "", | |||||
"charts": [], | "charts": [], | ||||
"content": "[{\"type\": \"header\", \"data\": {\"text\": \"Your Shortcuts\", \"level\": 4, \"col\": 12}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"ToDo\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Note\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"File\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Assignment Rule\", \"col\": 4}}, {\"type\": \"shortcut\", \"data\": {\"shortcut_name\": \"Auto Repeat\", \"col\": 4}}, {\"type\": \"spacer\", \"data\": {\"col\": 12}}, {\"type\": \"header\", \"data\": {\"text\": \"Reports & Masters\", \"level\": 4, \"col\": 12}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Tools\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Email\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Automation\", \"col\": 4}}, {\"type\": \"card\", \"data\": {\"card_name\": \"Event Streaming\", \"col\": 4}}]", | |||||
"creation": "2020-03-02 14:53:24.980279", | "creation": "2020-03-02 14:53:24.980279", | ||||
"developer_mode_only": 0, | "developer_mode_only": 0, | ||||
"disable_user_customization": 0, | "disable_user_customization": 0, | ||||
"docstatus": 0, | "docstatus": 0, | ||||
"doctype": "Workspace", | "doctype": "Workspace", | ||||
"extends": "", | |||||
"extends_another_page": 0, | "extends_another_page": 0, | ||||
"for_user": "", | |||||
"hide_custom": 0, | "hide_custom": 0, | ||||
"icon": "tool", | "icon": "tool", | ||||
"idx": 0, | "idx": 0, | ||||
"is_standard": 1, | |||||
"is_default": 0, | |||||
"is_standard": 0, | |||||
"label": "Tools", | "label": "Tools", | ||||
"links": [ | "links": [ | ||||
{ | { | ||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Tools", | "label": "Tools", | ||||
"link_count": 0, | |||||
"onboard": 0, | "onboard": 0, | ||||
"type": "Card Break" | "type": "Card Break" | ||||
}, | }, | ||||
@@ -25,6 +30,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "To Do", | "label": "To Do", | ||||
"link_count": 0, | |||||
"link_to": "ToDo", | "link_to": "ToDo", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 1, | "onboard": 1, | ||||
@@ -35,6 +41,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Calendar", | "label": "Calendar", | ||||
"link_count": 0, | |||||
"link_to": "Event", | "link_to": "Event", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 1, | "onboard": 1, | ||||
@@ -45,6 +52,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Note", | "label": "Note", | ||||
"link_count": 0, | |||||
"link_to": "Note", | "link_to": "Note", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 1, | "onboard": 1, | ||||
@@ -55,6 +63,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Files", | "label": "Files", | ||||
"link_count": 0, | |||||
"link_to": "File", | "link_to": "File", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -65,6 +74,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Activity", | "label": "Activity", | ||||
"link_count": 0, | |||||
"link_to": "activity", | "link_to": "activity", | ||||
"link_type": "Page", | "link_type": "Page", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -74,6 +84,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Email", | "label": "Email", | ||||
"link_count": 0, | |||||
"onboard": 0, | "onboard": 0, | ||||
"type": "Card Break" | "type": "Card Break" | ||||
}, | }, | ||||
@@ -82,6 +93,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Newsletter", | "label": "Newsletter", | ||||
"link_count": 0, | |||||
"link_to": "Newsletter", | "link_to": "Newsletter", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 1, | "onboard": 1, | ||||
@@ -92,6 +104,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Email Group", | "label": "Email Group", | ||||
"link_count": 0, | |||||
"link_to": "Email Group", | "link_to": "Email Group", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -101,6 +114,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Automation", | "label": "Automation", | ||||
"link_count": 0, | |||||
"onboard": 0, | "onboard": 0, | ||||
"type": "Card Break" | "type": "Card Break" | ||||
}, | }, | ||||
@@ -109,6 +123,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Assignment Rule", | "label": "Assignment Rule", | ||||
"link_count": 0, | |||||
"link_to": "Assignment Rule", | "link_to": "Assignment Rule", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -119,6 +134,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Milestone", | "label": "Milestone", | ||||
"link_count": 0, | |||||
"link_to": "Milestone", | "link_to": "Milestone", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -129,6 +145,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Auto Repeat", | "label": "Auto Repeat", | ||||
"link_count": 0, | |||||
"link_to": "Auto Repeat", | "link_to": "Auto Repeat", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -138,6 +155,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Event Streaming", | "label": "Event Streaming", | ||||
"link_count": 0, | |||||
"onboard": 0, | "onboard": 0, | ||||
"type": "Card Break" | "type": "Card Break" | ||||
}, | }, | ||||
@@ -146,6 +164,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Event Producer", | "label": "Event Producer", | ||||
"link_count": 0, | |||||
"link_to": "Event Producer", | "link_to": "Event Producer", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -156,6 +175,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Event Consumer", | "label": "Event Consumer", | ||||
"link_count": 0, | |||||
"link_to": "Event Consumer", | "link_to": "Event Consumer", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -166,6 +186,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Event Update Log", | "label": "Event Update Log", | ||||
"link_count": 0, | |||||
"link_to": "Event Update Log", | "link_to": "Event Update Log", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -176,6 +197,7 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Event Sync Log", | "label": "Event Sync Log", | ||||
"link_count": 0, | |||||
"link_to": "Event Sync Log", | "link_to": "Event Sync Log", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
@@ -186,19 +208,26 @@ | |||||
"hidden": 0, | "hidden": 0, | ||||
"is_query_report": 0, | "is_query_report": 0, | ||||
"label": "Document Type Mapping", | "label": "Document Type Mapping", | ||||
"link_count": 0, | |||||
"link_to": "Document Type Mapping", | "link_to": "Document Type Mapping", | ||||
"link_type": "DocType", | "link_type": "DocType", | ||||
"onboard": 0, | "onboard": 0, | ||||
"type": "Link" | "type": "Link" | ||||
} | } | ||||
], | ], | ||||
"modified": "2020-12-01 13:38:39.950350", | |||||
"modified": "2021-08-05 12:16:02.839180", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Automation", | "module": "Automation", | ||||
"name": "Tools", | "name": "Tools", | ||||
"onboarding": "", | |||||
"owner": "Administrator", | "owner": "Administrator", | ||||
"parent_page": "", | |||||
"pin_to_bottom": 0, | "pin_to_bottom": 0, | ||||
"pin_to_top": 0, | "pin_to_top": 0, | ||||
"public": 1, | |||||
"restrict_to_domain": "", | |||||
"roles": [], | |||||
"sequence_id": 26, | |||||
"shortcuts": [ | "shortcuts": [ | ||||
{ | { | ||||
"label": "ToDo", | "label": "ToDo", | ||||
@@ -225,5 +254,6 @@ | |||||
"link_to": "Auto Repeat", | "link_to": "Auto Repeat", | ||||
"type": "DocType" | "type": "DocType" | ||||
} | } | ||||
] | |||||
], | |||||
"title": "Tools" | |||||
} | } |
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
""" | """ | ||||
bootstrap client session | bootstrap client session | ||||
""" | """ | ||||
@@ -105,8 +105,8 @@ def load_conf_settings(bootinfo): | |||||
if key in conf: bootinfo[key] = conf.get(key) | if key in conf: bootinfo[key] = conf.get(key) | ||||
def load_desktop_data(bootinfo): | def load_desktop_data(bootinfo): | ||||
from frappe.desk.desktop import get_desk_sidebar_items | |||||
bootinfo.allowed_workspaces = get_desk_sidebar_items() | |||||
from frappe.desk.desktop import get_wspace_sidebar_items | |||||
bootinfo.allowed_workspaces = get_wspace_sidebar_items().get('pages') | |||||
bootinfo.module_page_map = get_controller("Workspace").get_module_page_map() | bootinfo.module_page_map = get_controller("Workspace").get_module_page_map() | ||||
bootinfo.dashboards = frappe.get_all("Dashboard") | bootinfo.dashboards = frappe.get_all("Dashboard") | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import os | import os | ||||
import re | import re | ||||
import json | import json | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe, json | import frappe, json | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2018, Frappe Technologies and contributors | # Copyright (c) 2018, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
import frappe.model | import frappe.model | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Web Notes Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Web Notes Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import sys | import sys | ||||
import click | import click | ||||
@@ -486,15 +486,26 @@ frappe.db.connect() | |||||
@click.command('console') | @click.command('console') | ||||
@click.option( | |||||
'--autoreload', | |||||
is_flag=True, | |||||
help="Reload changes to code automatically" | |||||
) | |||||
@pass_context | @pass_context | ||||
def console(context): | |||||
def console(context, autoreload=False): | |||||
"Start ipython console for a site" | "Start ipython console for a site" | ||||
site = get_site(context) | site = get_site(context) | ||||
frappe.init(site=site) | frappe.init(site=site) | ||||
frappe.connect() | frappe.connect() | ||||
frappe.local.lang = frappe.db.get_default("lang") | frappe.local.lang = frappe.db.get_default("lang") | ||||
import IPython | |||||
from IPython.terminal.embed import InteractiveShellEmbed | |||||
terminal = InteractiveShellEmbed() | |||||
if autoreload: | |||||
terminal.extension_manager.load_extension("autoreload") | |||||
terminal.run_line_magic("autoreload", "2") | |||||
all_apps = frappe.get_installed_apps() | all_apps = frappe.get_installed_apps() | ||||
failed_to_import = [] | failed_to_import = [] | ||||
@@ -509,7 +520,9 @@ def console(context): | |||||
if failed_to_import: | if failed_to_import: | ||||
print("\nFailed to import:\n{}".format(", ".join(failed_to_import))) | print("\nFailed to import:\n{}".format(", ".join(failed_to_import))) | ||||
IPython.embed(display_banner="", header="", colors="neutral") | |||||
terminal.colors = "neutral" | |||||
terminal.display_banner = False | |||||
terminal() | |||||
@click.command('run-tests') | @click.command('run-tests') | ||||
@@ -524,7 +537,7 @@ def console(context): | |||||
@click.option('--skip-test-records', is_flag=True, default=False, help="Don't create test records") | @click.option('--skip-test-records', is_flag=True, default=False, help="Don't create test records") | ||||
@click.option('--skip-before-tests', is_flag=True, default=False, help="Don't run before tests hook") | @click.option('--skip-before-tests', is_flag=True, default=False, help="Don't run before tests hook") | ||||
@click.option('--junit-xml-output', help="Destination file path for junit xml report") | @click.option('--junit-xml-output', help="Destination file path for junit xml report") | ||||
@click.option('--failfast', is_flag=True, default=False) | |||||
@click.option('--failfast', is_flag=True, default=False, help="Stop the test run on the first error or failure") | |||||
@pass_context | @pass_context | ||||
def run_tests(context, app=None, module=None, doctype=None, test=(), profile=False, | def run_tests(context, app=None, module=None, doctype=None, test=(), profile=False, | ||||
coverage=False, junit_xml_output=False, ui_tests = False, doctype_list_path=None, | coverage=False, junit_xml_output=False, ui_tests = False, doctype_list_path=None, | ||||
@@ -589,24 +602,26 @@ def run_ui_tests(context, app, headless=False, parallel=True, ci_build_id=None): | |||||
admin_password = frappe.get_conf(site).admin_password | admin_password = frappe.get_conf(site).admin_password | ||||
# override baseUrl using env variable | # override baseUrl using env variable | ||||
site_env = 'CYPRESS_baseUrl={}'.format(site_url) | |||||
password_env = 'CYPRESS_adminPassword={}'.format(admin_password) if admin_password else '' | |||||
site_env = f'CYPRESS_baseUrl={site_url}' | |||||
password_env = f'CYPRESS_adminPassword={admin_password}' if admin_password else '' | |||||
os.chdir(app_base_path) | os.chdir(app_base_path) | ||||
node_bin = subprocess.getoutput("npm bin") | node_bin = subprocess.getoutput("npm bin") | ||||
cypress_path = "{0}/cypress".format(node_bin) | |||||
plugin_path = "{0}/../cypress-file-upload".format(node_bin) | |||||
cypress_path = f"{node_bin}/cypress" | |||||
plugin_path = f"{node_bin}/../cypress-file-upload" | |||||
testing_library_path = f"{node_bin}/../@testing-library" | |||||
# check if cypress in path...if not, install it. | # check if cypress in path...if not, install it. | ||||
if not ( | if not ( | ||||
os.path.exists(cypress_path) | os.path.exists(cypress_path) | ||||
and os.path.exists(plugin_path) | and os.path.exists(plugin_path) | ||||
and os.path.exists(testing_library_path) | |||||
and cint(subprocess.getoutput("npm view cypress version")[:1]) >= 6 | and cint(subprocess.getoutput("npm view cypress version")[:1]) >= 6 | ||||
): | ): | ||||
# install cypress | # install cypress | ||||
click.secho("Installing Cypress...", fg="yellow") | click.secho("Installing Cypress...", fg="yellow") | ||||
frappe.commands.popen("yarn add cypress@^6 cypress-file-upload@^5 --no-lockfile") | |||||
frappe.commands.popen("yarn add cypress@^6 cypress-file-upload@^5 @testing-library/cypress@^8 --no-lockfile") | |||||
# run for headless mode | # run for headless mode | ||||
run_or_open = 'run --browser firefox --record' if headless else 'open' | run_or_open = 'run --browser firefox --record' if headless else 'open' | ||||
@@ -617,7 +632,7 @@ def run_ui_tests(context, app, headless=False, parallel=True, ci_build_id=None): | |||||
formatted_command += ' --parallel' | formatted_command += ' --parallel' | ||||
if ci_build_id: | if ci_build_id: | ||||
formatted_command += ' --ci-build-id {}'.format(ci_build_id) | |||||
formatted_command += f' --ci-build-id {ci_build_id}' | |||||
click.secho("Running Cypress...", fg="yellow") | click.secho("Running Cypress...", fg="yellow") | ||||
frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True) | frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True) | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||||
# License: GNU General Public License v3. See license.txt | |||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and contributors | # Copyright (c) 2015, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and Contributors | # Copyright (c) 2015, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe, unittest | import frappe, unittest | ||||
from frappe.contacts.doctype.address.address import get_address_display | from frappe.contacts.doctype.address.address import get_address_display | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and contributors | # Copyright (c) 2015, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and Contributors | # Copyright (c) 2015, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe, unittest | import frappe, unittest | ||||
class TestAddressTemplate(unittest.TestCase): | class TestAddressTemplate(unittest.TestCase): | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||||
# License: GNU General Public License v3. See license.txt | |||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.utils import cstr, has_gravatar | from frappe.utils import cstr, has_gravatar | ||||
from frappe import _ | from frappe import _ | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2017, Frappe Technologies and Contributors | # Copyright (c) 2017, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import unittest | import unittest | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
# import frappe | # import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
# import frappe | # import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2017, Frappe Technologies and contributors | # Copyright (c) 2017, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2017, Frappe Technologies and Contributors | # Copyright (c) 2017, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import unittest | import unittest | ||||
class TestGender(unittest.TestCase): | class TestGender(unittest.TestCase): | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2017, Frappe Technologies and contributors | # Copyright (c) 2017, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2017, Frappe Technologies and Contributors | # Copyright (c) 2017, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import unittest | import unittest | ||||
class TestSalutation(unittest.TestCase): | class TestSalutation(unittest.TestCase): | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors | # Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
@@ -1,2 +1,2 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE |
@@ -1,3 +1,3 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -29,4 +29,5 @@ def make_access_log(doctype=None, document=None, method=None, file_type=None, | |||||
doc.insert(ignore_permissions=True) | doc.insert(ignore_permissions=True) | ||||
# `frappe.db.commit` added because insert doesnt `commit` when called in GET requests like `printview` | # `frappe.db.commit` added because insert doesnt `commit` when called in GET requests like `printview` | ||||
frappe.db.commit() | |||||
if frappe.request and frappe.request.method == 'GET': | |||||
frappe.db.commit() |
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and Contributors | # Copyright (c) 2019, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
# imports - standard imports | # imports - standard imports | ||||
import unittest | import unittest | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2017, Frappe Technologies and contributors | # Copyright (c) 2017, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
from frappe import _ | from frappe import _ | ||||
from frappe.utils import get_fullname, now | from frappe.utils import get_fullname, now | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# License: See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import frappe.permissions | import frappe.permissions | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and Contributors | # Copyright (c) 2015, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import unittest | import unittest | ||||
import time | import time | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
import json | import json | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and Contributors | # Copyright (c) 2019, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe, json | import frappe, json | ||||
import unittest | import unittest | ||||
@@ -30,7 +30,7 @@ class TestComment(unittest.TestCase): | |||||
from frappe.website.doctype.blog_post.test_blog_post import make_test_blog | from frappe.website.doctype.blog_post.test_blog_post import make_test_blog | ||||
test_blog = make_test_blog() | test_blog = make_test_blog() | ||||
frappe.db.sql("delete from `tabComment` where reference_doctype = 'Blog Post'") | |||||
frappe.db.delete("Comment", {"reference_doctype": "Blog Post"}) | |||||
from frappe.templates.includes.comments.comments import add_comment | from frappe.templates.includes.comments.comments import add_comment | ||||
add_comment('Good comment with 10 chars', 'test@test.com', 'Good Tester', | add_comment('Good comment with 10 chars', 'test@test.com', 'Good Tester', | ||||
@@ -41,7 +41,7 @@ class TestComment(unittest.TestCase): | |||||
reference_name = test_blog.name | reference_name = test_blog.name | ||||
))[0].published, 1) | ))[0].published, 1) | ||||
frappe.db.sql("delete from `tabComment` where reference_doctype = 'Blog Post'") | |||||
frappe.db.delete("Comment", {"reference_doctype": "Blog Post"}) | |||||
add_comment('pleez vizits my site http://mysite.com', 'test@test.com', 'bad commentor', | add_comment('pleez vizits my site http://mysite.com', 'test@test.com', 'bad commentor', | ||||
'Blog Post', test_blog.name, test_blog.route) | 'Blog Post', test_blog.name, test_blog.route) | ||||
@@ -1,3 +1,3 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
from collections import Counter | from collections import Counter | ||||
import frappe | import frappe | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import json | import json | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import unittest | import unittest | ||||
from urllib.parse import quote | from urllib.parse import quote | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and contributors | # Copyright (c) 2015, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and Contributors | # Copyright (c) 2015, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import unittest | import unittest | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and contributors | # Copyright (c) 2015, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies and Contributors | # Copyright (c) 2015, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
import unittest | import unittest | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and contributors | # Copyright (c) 2019, Frappe Technologies and contributors | ||||
# For license information, please see license.txt | |||||
# License: MIT. See LICENSE | |||||
import os | import os | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import typing | import typing | ||||
@@ -1,5 +1,5 @@ | |||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||
import os | import os | ||||
import io | import io | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2020, Frappe Technologies and Contributors | # Copyright (c) 2020, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
# import frappe | # import frappe | ||||
import unittest | import unittest | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and Contributors | # Copyright (c) 2019, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import unittest | import unittest | ||||
import frappe | import frappe | ||||
from frappe.core.doctype.data_import.exporter import Exporter | from frappe.core.doctype.data_import.exporter import Exporter | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
# Copyright (c) 2019, Frappe Technologies and Contributors | # Copyright (c) 2019, Frappe Technologies and Contributors | ||||
# See license.txt | |||||
# License: MIT. See LICENSE | |||||
import unittest | import unittest | ||||
import frappe | import frappe | ||||
from frappe.core.doctype.data_import.importer import Importer | from frappe.core.doctype.data_import.importer import Importer | ||||
@@ -1,3 +1,3 @@ | |||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
# MIT License. See license.txt | |||||
# License: MIT. See LICENSE | |||||