diff --git a/.github/workflows/es-tests.yml b/.github/workflows/es-tests.yml new file mode 100644 index 000000000..4ff5ccdcc --- /dev/null +++ b/.github/workflows/es-tests.yml @@ -0,0 +1,204 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Elastic Search Tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + inputs: + environment: + description: 'Environment to run tests against' + required: true + default: 'staging' + type: choice + options: + - staging + - production + +jobs: + set_matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix-manual.outputs.matrix || steps.set-matrix-default.outputs.matrix }} + steps: + - id: set-matrix-manual + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + echo "::set-output name=matrix::{\"environment\": [\"${{ inputs.environment }}\"]}" + - id: set-matrix-default + if: ${{ !contains(github.event_name , 'dispatch') }} + run: | + echo "::set-output name=matrix::{\"environment\": [\"staging\"]}" + build: + needs: set_matrix + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.set_matrix.outputs.matrix) }} + concurrency: + group: ${{ github.workflow }}-${{ matrix.environment }} + cancel-in-progress: true + name: ES Test on '${{ matrix.environment }}' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.9 + uses: actions/setup-python@v2 + with: + python-version: 3.9 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r ElasticSearchTests/requires.txt + + - name: ES Test with pytest + env: + DIMAGIQA_ENV: ${{ matrix.environment }} #${{ secrets.DIMAGIQA_URL }} + DIMAGIQA_LOGIN_USERNAME: ${{ secrets.DIMAGIQA_LOGIN_USERNAME }} + DIMAGIQA_LOGIN_PASSWORD: ${{ secrets.DIMAGIQA_LOGIN_PASSWORD }} + DIMAGIQA_MAIL_USERNAME: ${{ secrets.DIMAGIQA_MAIL_USERNAME }} + DIMAGIQA_MAIL_PASSWORD: ${{ secrets.DIMAGIQA_MAIL_PASSWORD }} + DIMAGIQA_BS_USER: ${{ secrets.DIMAGIQA_BS_USER }} + DIMAGIQA_BS_KEY: ${{ secrets.DIMAGIQA_BS_KEY }} + DIMAGIQA_STAGING_AUTH_KEY: ${{ secrets.DIMAGIQA_STAGING_AUTH_KEY }} + DIMAGIQA_PROD_AUTH_KEY: ${{ secrets.DIMAGIQA_PROD_AUTH_KEY }} + DIMAGIQA_INVITED_WEBUSER_PASSWORD: ${{ secrets.DIMAGIQA_INVITED_WEBUSER_PASSWORD }} + DIMAGIQA_IMAP_PASSWORD: ${{secrets.DIMAGIQA_IMAP_PASSWORD}} + run: | + echo "client_payload: ${{ toJson(github.event.client_payload) }}" + echo "matrix environment: ${{ matrix.environment }}" + echo "NOW=$(date +'%m-%d %H:%M')" >> $GITHUB_ENV + echo ${{env.NOW}} + pytest -v --rootdir= ElasticSearchTests/testCases -n 4 --dist=loadfile --reruns 1 --html=es_report_${{ matrix.environment }}.html + + - name: Set email vars + if: ${{ failure() }} + id: configure_email + uses: actions/github-script@v6 + env: + JOB_STATUS: ${{ job.status }} + CC_ENV: ${{ matrix.environment }} + with: + script: | + const { promises: fs } = require('fs') + + const {JOB_STATUS, NOW, CC_ENV, GITHUB_HEAD_REF} = process.env + const prefix = `[${CC_ENV}] ES Tests - ${JOB_STATUS.toUpperCase()} - Run #${context.runNumber}` + const suffix = `at ${NOW}` + + let subject = `${prefix} on "deploy_success" ${suffix}` + if (context.eventName !== "repository_dispatch") { + subject = `${prefix} on branch "${GITHUB_HEAD_REF}" ${suffix}` + } + + let bodyFile = './common_utilities/mail_templates/email_pass.md' + if (JOB_STATUS !== 'success') { + bodyFile = './common_utilities/mail_templates/email_fail.md' + } + + let actionRunLink = context.payload.repository.html_url + `/actions/runs/${context.runId}` + let testSuite = 'ES Test' + let bodyContent = await fs.readFile(bodyFile, 'utf8') + bodyContent = bodyContent.replace(/{{actionRunLink}}/g, actionRunLink) + .replace(/{{runNumber}}/g, context.runNumber) + .replace(/{{environment}}/g, CC_ENV) + .replace(/{{testSuite}}/g, testSuite) + + let receivers = 'qa-automation@dimagi.com' + if (context.eventName !== "pull_request" || context.eventName !== "push") { + receivers = 'qa@dimagi.com' + } + + return { + "subject": subject, + "body": bodyContent, + "reference": Math.random().toString(36).substr(2), // used to prevent threading of similar emails + "receivers": receivers + } + + - name: Send Result Email + if: ${{ failure() }} + uses: dawidd6/action-send-mail@v3 + with: + server_address: smtp.gmail.com + server_port: 465 + username: ${{secrets.DIMAGIQA_MAIL_USERNAME}} + password: ${{secrets.DIMAGIQA_MAIL_PASSWORD}} + subject: ${{ fromJSON(steps.configure_email.outputs.result).subject }} + to: ${{ fromJSON(steps.configure_email.outputs.result).receivers }} + from: <${{secrets.DIMAGIQA_MAIL_USERNAME}}> + html_body: ${{ fromJSON(steps.configure_email.outputs.result).body }} + convert_markdown: true + attachments: ${{ github.workspace }}/es_report_${{ matrix.environment }}.html + in_reply_to: ${{ fromJSON(steps.configure_email.outputs.result).reference }} + + - name: Post to Slack channel on Failure + id: slack + uses: slackapi/slack-github-action@v1.23.0 + if: failure() + with: + payload: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": " Konnichiwa :alphabet-yellow-q::alphabet-yellow-a: 👋 \n*${{ github.workflow }}* were just triggered!" + } + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "*Environment: *\n ${{ matrix.environment }} \n" + }, + { + "type": "mrkdwn", + "text": " " + }, + { + "type": "mrkdwn", + "text": "*Status: *\n ${{ job.status }} :x:" + } + ] + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Here's the corresponding workflow execution :arrow_right::arrow_right:" + }, + "accessory": { + "type": "button", + "text": { + "type": "plain_text", + "text": "View on Github", + "emoji": true + }, + "value": "click_me_123", + "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", + "action_id": "button-action", + "style": "danger" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_SMOKE }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + - name: Archive test results + if: ${{ success() || failure() }} + uses: actions/upload-artifact@v2 + with: + name: test-result-reports-${{ matrix.environment }} + path: ${{ github.workspace }}/es_report_${{ matrix.environment }}.html + retention-days: 2 diff --git a/.gitignore b/.gitignore index 3d2600382..8fa8b54ae 100644 --- a/.gitignore +++ b/.gitignore @@ -234,5 +234,9 @@ Features/Lookuptable/settings.cfg Features/Lookuptable/report.html Features/Lookuptable/testCases/report.html +#Ignoring compliled files of ElasticSearchTests +ElasticSearchTests/settings.cfg +ElasticSearchTests/report.html +ElasticSearchTests/testCases/report.html diff --git a/ElasticSearchTests/README.md b/ElasticSearchTests/README.md new file mode 100644 index 000000000..0ba768627 --- /dev/null +++ b/ElasticSearchTests/README.md @@ -0,0 +1,60 @@ +## Elastic Search Test Script + +ES tests ensure that the Elastic Search functionalities are working and there are no showstoppers in the ES upgrades deployed to environments.\ +The automated tests comprises of [these tests.](https://docs.google.com/spreadsheets/d/1ahqBcHWlp1YoxwkIpSc_zV25PjY4V5j6GW4jb3LOyuc/edit#gid=1461812550) + +## Executing Scripts + +### On Local Machine + +#### Setting up test environment + +```sh + +# create and activate a virtualenv using your preferred method. Example: +python -m venv venv +source venv/bin/activate + + +# install requirements +pip install -r requires.txt + +``` + +[More on setting up virtual environments](https://confluence.dimagi.com/display/GTD/QA+and+Python+Virtual+Environments) + + +#### Running Tests + + + - Copy `settings-sample.cfg` to `settings.cfg` and populate `settings.cfg` for +the environment you want to test. +- Run tests using pytest command like: + +```sh + +# To execute all the test cases +pytest -v --rootdir= ElasticSearchTests/testCases + +``` +- You could also pass the following arguments + - ` -n 3 --dist=loadfile` - This will run the tests parallelly in 3 instances. The number of reruns is configurable. + - ` --reruns 1` - This will re-run the tests once in case of failures.The number of reruns is configurable too. + +### Trigger Manually on Gitaction + +clone this repository + +To manually trigger the script, + - Go to [Gitactions](https://github.com/dimagi/dimagi-qa/actions/) + - Select the desired workflow, here [ES Tests action](https://github.com/dimagi/dimagi-qa/actions/workflows/es-tests.yml) + - Run workflow + - Select workflow as ```master``` + - Select the environment as desired + - Run! + +If you are a part of the QA team, you'll receive emails for the result of the run after it's complete. + +clone this repository + +Besides, you should be able to find the zipped results in the **Artifacts** section, of the corresponding run (after it's complete). diff --git a/ElasticSearchTests/__init__.py b/ElasticSearchTests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/requires.txt b/ElasticSearchTests/requires.txt new file mode 100644 index 000000000..e39149e32 --- /dev/null +++ b/ElasticSearchTests/requires.txt @@ -0,0 +1,20 @@ +## Stores information about all the libraries, modules, and packages that are used in this project. + +flake8>=3.8.4 +pandas>=1.2.2 +pytest +pytest-html +py +openpyxl +selenium == 4.11.0 +pytest-rerunfailures +pytest-xdist +pytest-xdist[psutil] +pytest-order +python-dateutil +natsort +pyotp +imap-tools +beautifulsoup4 +html5lib +requests \ No newline at end of file diff --git a/ElasticSearchTests/settings-sample.cfg b/ElasticSearchTests/settings-sample.cfg new file mode 100644 index 000000000..ba535aaa4 --- /dev/null +++ b/ElasticSearchTests/settings-sample.cfg @@ -0,0 +1,19 @@ +[default] +# This is the environment url of commcare +url = https://www.commcarehq.org/ +# Login username of the webuser +login_username = +# Login password of the webuser +login_password = +# This is a preconfigured browsertack username for mobile tests +bs_user = +# This is a preconfigured browsertack key used for mobile tests +bs_key = +# This is a preconfigured authentication key used for 2FA tests on staging +staging_auth_key = +# This is a preconfigured authentication key used for 2FA tests on prod +prod_auth_key = +# This is a preconfigured password for the user used to test web user invitation tests +invited_webuser_password = +# This is a preconfigured password for the email account used for saved reports verification +imap_password = \ No newline at end of file diff --git a/ElasticSearchTests/settings.cfg b/ElasticSearchTests/settings.cfg new file mode 100644 index 000000000..17ec21a8a --- /dev/null +++ b/ElasticSearchTests/settings.cfg @@ -0,0 +1,7 @@ +[default] +url = https://staging.commcarehq.org/ +login_username = automation.user.commcarehq@gmail.com +login_password = pass@123 +staging_auth_key = "DRCAKX6AG3V3Q7JWV27KIPOWVMAYJ3R4" +prod_auth_key = "YRJSX3BARTDVYUUQKIQUX3EIKQUZZS5P" +imap_password = gpzwiwkpseyhjoub diff --git a/ElasticSearchTests/testCases/__init__.py b/ElasticSearchTests/testCases/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testCases/conftest.py b/ElasticSearchTests/testCases/conftest.py new file mode 100644 index 000000000..9e0d8a922 --- /dev/null +++ b/ElasticSearchTests/testCases/conftest.py @@ -0,0 +1,72 @@ +import os + +from configparser import ConfigParser +from pathlib import Path +from common_utilities.fixtures import * + +""""This file provides fixture functions for driver initialization""" + +global driver + + +@pytest.fixture(scope="session") +def environment_settings_hq(): + """Load settings from os.environ + + Names of environment variables: + DIMAGIQA_URL + DIMAGIQA_LOGIN_USERNAME + DIMAGIQA_LOGIN_PASSWORD + DIMAGIQA_MAIL_USERNAME + DIMAGIQA_MAIL_PASSWORD + + See https://docs.github.com/en/actions/reference/encrypted-secrets + for instructions on how to set them. + """ + settings = {} + for name in ["url", "login_username", "login_password", "mail_username", + "mail_password", "bs_user", "bs_key", "staging_auth_key", "prod_auth_key", "invited_webuser_password", "imap_password"]: + + var = f"DIMAGIQA_{name.upper()}" + if var in os.environ: + settings[name] = os.environ[var] + if "url" not in settings: + env = os.environ.get("DIMAGIQA_ENV") or "staging" + subdomain = "www" if env == "production" else env + # updates the url with the project domain while testing in CI + project = "a/qa-automation-prod" if env == "production" else "a/qa-automation" + settings["url"] = f"https://{subdomain}.commcarehq.org/{project}" + return settings + + +@pytest.fixture(scope="session", autouse=True) +def settings(environment_settings_hq): + if os.environ.get("CI") == "true": + settings = environment_settings_hq + settings["CI"] = "true" + if any(x not in settings for x in ["url", "login_username", "login_password", + "mail_username", "mail_password", "bs_user", "bs_key", "staging_auth_key", + "prod_auth_key", "invited_webuser_password", "imap_password"]): + lines = environment_settings_hq.__doc__.splitlines() + vars_ = "\n ".join(line.strip() for line in lines if "DIMAGIQA_" in line) + raise RuntimeError( + f"Environment variables not set:\n {vars_}\n\n" + "See https://docs.github.com/en/actions/reference/encrypted-secrets " + "for instructions on how to set them." + ) + return settings + path = Path(__file__).parent.parent / "settings.cfg" + if not path.exists(): + raise RuntimeError( + f"Not found: {path}\n\n" + "Copy settings-sample.cfg to settings.cfg and populate " + "it with values for the environment you want to test." + ) + settings = ConfigParser() + settings.read(path) + # updates the url with the project domain while testing in local + if settings["default"]["url"] == "https://www.commcarehq.org/": + settings["default"]["url"] = f"{settings['default']['url']}a/qa-automation-prod" + else: + settings["default"]["url"] = f"{settings['default']['url']}a/qa-automation" + return settings["default"] diff --git a/ElasticSearchTests/testCases/report.html b/ElasticSearchTests/testCases/report.html new file mode 100644 index 000000000..86d1e6629 --- /dev/null +++ b/ElasticSearchTests/testCases/report.html @@ -0,0 +1,527 @@ + + + + + report.html + + + +

report.html

+

Report generated on 21-Dec-2023 at 12:28:38 by pytest-html v3.2.0

+

Environment

+ + + + + + + + + + + + + + + +
JAVA_HOMEC:\Program Files\Java\jdk-11.0.14
Packages{"pluggy": "1.0.0", "py": "1.11.0", "pytest": "7.4.0"}
PlatformWindows-10-10.0.19044-SP0
Plugins{"anyio": "3.7.1", "depends": "1.0.1", "forked": "1.4.0", "html": "3.2.0", "metadata": "2.0.1", "order": "1.1.0", "rerunfailures": "12.0", "xdist": "3.3.1"}
Python3.10.3
+

Summary

+

1 tests ran in 420.83 seconds.

+ 1 passed, 0 skipped, 0 failed, 0 errors, 0 expected failures, 0 unexpected passes, 0 rerun +

Results

+ + + + + + + + + + + + + + + + +
ResultTagsTestDuration
Passedreports, loginElasticSearchTests/testCases/test_06_form_completion_time.py::test_case_03_save_report_and_favorite415.86
+
-----------------------------Captured stdout setup------------------------------
Chrome version: 120.0.6099.110 +Non SSO workflow +
------------------------------Captured stdout call------------------------------
no alert +11 +A Look up for users is successfully loaded +3 +Select Application... +Select Application... is present as default value +Select a Menu +Select a Menu is present as default value +List to compare: ['Select a Menu', 'Case Change', 'Case List'] +Select a Menu +Case Change +Case List +Option list ['Select a Menu', 'Case Change', 'Case List'] +All module/form options are present in the dropdown +Select a Form +Select a Form is present as default value +List to compare: ['Select a Form', 'Android Test Form', 'Followup Form', 'Registration Form'] +Select a Form +Android Test Form +Followup Form +Registration Form +Option list ['Select a Form', 'Android Test Form', 'Followup Form', 'Registration Form'] +All module/form options are present in the dropdown +2023-12-14 to 2023-12-21 +2023-12-14 to 2023-12-21 +Report loaded successfully! +Group User appiumtest is present in results. +Group User formplayer_user is present in results. +No Favorites yet. +Last 7 days +Date range is matching +Save Report Form is closed +Error is correctly displayed +Last 7 days +Date range is matching +Report Saved successfully! +Report name: Saved Form Completion Time Report usrejv +Favorites added. +Group User appiumtest is present in results. +Group User formplayer_user is present in results. +Report Present! +Deleted Saved Report +Deleted Report Successfully +No Favorites yet. +
\ No newline at end of file diff --git a/ElasticSearchTests/testCases/test_01_worker_activity.py b/ElasticSearchTests/testCases/test_01_worker_activity.py new file mode 100644 index 000000000..f2ac16f9d --- /dev/null +++ b/ElasticSearchTests/testCases/test_01_worker_activity.py @@ -0,0 +1,101 @@ +import pytest + +from ElasticSearchTests.testPages.data.reassign_cases_page import ReassignCasesPage +from HQSmokeTests.testPages.email.email_verification import EmailVerification +from HQSmokeTests.testPages.home.home_page import HomePage +from ElasticSearchTests.userInputs.user_inputs import UserData +from ElasticSearchTests.testPages.worker_activity.worker_activity_page import WorkerActivityPage + +""""Contains all test cases that aren't specifically related any menu modules""" + + +@pytest.mark.login +@pytest.mark.reports +def test_case_01_worker_activity_report_no_case_type_filters(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = WorkerActivityPage(driver) + activity.hide_filters() + activity.show_filters() + activity.worker_activity_report_no_case_type() + activity.verify_users_in_the_group() + + +@pytest.mark.login +@pytest.mark.reports +def test_case_02_view_by_group_with_case_type(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = WorkerActivityPage(driver) + activity.worker_activity_report_group_case_type() + +@pytest.mark.login +@pytest.mark.reports +def test_case_03_pagination(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = WorkerActivityPage(driver) + activity.worker_activity_pagination_list() + activity.verify_pagination_dropdown() + activity.verify_sorted_list() + +@pytest.mark.login +@pytest.mark.reports +def test_case_04_date_range(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = WorkerActivityPage(driver) + activity.worker_activity_search(UserData.date_range[0]) + report.reports_menu() + activity.worker_activity_search(UserData.date_range[1]) + report.reports_menu() + activity.worker_activity_search(UserData.date_range[2]) + report.reports_menu() + activity.worker_activity_search_custom_date() + activity.verify_users_in_the_group() + +@pytest.mark.login +@pytest.mark.reports +def test_case_05_save_report_and_favorite(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = WorkerActivityPage(driver) + activity.worker_activity_save_report() + +@pytest.mark.login +@pytest.mark.reports +def test_case_06_export_to_excel(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = WorkerActivityPage(driver) + web_data = activity.export_worker_activity_to_excel() + email = EmailVerification(settings) + link = email.get_hyperlink_from_latest_email(UserData.worker_report, settings['url']) + activity.compare_wa_with_email(link, web_data) + +@pytest.mark.login +@pytest.mark.reports +def test_case_07_email_report(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = WorkerActivityPage(driver) + web_data, subject = activity.export_worker_activity_email() + email = EmailVerification(settings) + table_data = email.get_email_body_from_latest_email(subject, settings['url']) + activity.compare_wa_with_html_table(table_data, web_data) + + + +@pytest.mark.login +@pytest.mark.reports +@pytest.mark.xfail +def test_case_08_case_assign(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = WorkerActivityPage(driver) + actives, totals, text = activity.worker_activity_case_assign_data() + home.data_menu() + reassign = ReassignCasesPage(driver, settings) + reassign.reassign_case(text) + home.reports_menu() + activity.verify_assigned_cases_count(actives, totals) diff --git a/ElasticSearchTests/testCases/test_02_daily_form_activity.py b/ElasticSearchTests/testCases/test_02_daily_form_activity.py new file mode 100644 index 000000000..de1a4aa06 --- /dev/null +++ b/ElasticSearchTests/testCases/test_02_daily_form_activity.py @@ -0,0 +1,91 @@ +import pytest + +from ElasticSearchTests.testPages.daily_form_activity.daily_form_activity_page import DailyFormActivityPage +from ElasticSearchTests.testPages.data.reassign_cases_page import ReassignCasesPage +from HQSmokeTests.testPages.email.email_verification import EmailVerification +from HQSmokeTests.testPages.home.home_page import HomePage +from ElasticSearchTests.userInputs.user_inputs import UserData +from ElasticSearchTests.testPages.daily_form_activity.daily_form_activity_page import DailyFormActivityPage + +""""Contains all test cases that aren't specifically related any menu modules""" + + +@pytest.mark.login +@pytest.mark.reports +def test_case_01_daily_form_activity_report_fields_filters_columns(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = DailyFormActivityPage(driver) + activity.verify_daily_activity_page_fields() + activity.hide_filters() + activity.show_filters() + activity.verify_table_columns() + activity.verify_users_in_the_group() + +def test_case_02_date_range(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = DailyFormActivityPage(driver) + activity.daily_form_activity_search(UserData.date_range[0]) + report.reports_menu() + activity.daily_form_activity_search(UserData.date_range[1]) + report.reports_menu() + activity.daily_form_activity_search(UserData.date_range[2]) + report.reports_menu() + activity.daily_form_activity_search_custom_date() + + +@pytest.mark.login +@pytest.mark.reports +def test_case_03_pagination(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = DailyFormActivityPage(driver) + activity.daily_form_activity_pagination_list() + activity.verify_pagination_dropdown() + activity.verify_sorted_list() + +@pytest.mark.login +@pytest.mark.reports +def test_case_04_save_report_and_favorite(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = DailyFormActivityPage(driver) + activity.daily_form_activity_save_report() + +@pytest.mark.login +@pytest.mark.reports +def test_case_05_export_to_excel(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = DailyFormActivityPage(driver) + web_data = activity.export_daily_form_activity_to_excel() + email = EmailVerification(settings) + link = email.get_hyperlink_from_latest_email(UserData.daily_form_report, settings['url']) + activity.compare_dfa_with_email(link, web_data) + +@pytest.mark.login +@pytest.mark.reports +def test_case_06_email_report(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = DailyFormActivityPage(driver) + web_data, subject = activity.export_daily_form_activity_email() + email = EmailVerification(settings) + table_data = email.get_email_body_from_latest_email(subject, settings['url']) + activity.compare_dfa_with_html_table(table_data, web_data) + + + +@pytest.mark.login +@pytest.mark.reports +@pytest.mark.xfail +def test_case_07_user_type_filter_by(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = DailyFormActivityPage(driver) + activity.daily_form_activity_users_active() + activity.daily_form_activity_users_deactivated() + activity.filter_dates_and_verify(UserData.filter_dates_by[0]) + activity.filter_dates_and_verify(UserData.filter_dates_by[1]) + diff --git a/ElasticSearchTests/testCases/test_03_case_activity.py b/ElasticSearchTests/testCases/test_03_case_activity.py new file mode 100644 index 000000000..84386c440 --- /dev/null +++ b/ElasticSearchTests/testCases/test_03_case_activity.py @@ -0,0 +1,77 @@ +import pytest + +from HQSmokeTests.testPages.email.email_verification import EmailVerification +from HQSmokeTests.testPages.home.home_page import HomePage +from ElasticSearchTests.userInputs.user_inputs import UserData +from ElasticSearchTests.testPages.case_activity.case_activity_page import CaseActivityPage + +""""Contains all test cases that aren't specifically related any menu modules""" + + +@pytest.mark.login +@pytest.mark.reports +def test_case_01_case_activity_report_fields_filters_columns(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = CaseActivityPage(driver) + activity.verify_case_activity_page_fields() + activity.hide_filters() + activity.show_filters() + activity.verify_table_columns() + activity.verify_users_in_the_group() + +@pytest.mark.login +@pytest.mark.reports +@pytest.mark.xfail +def test_case_02_pagination(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = CaseActivityPage(driver) + activity.case_activity_pagination_list() + activity.verify_pagination_dropdown() + activity.verify_sorted_list() + + +@pytest.mark.login +@pytest.mark.reports +def test_case_03_save_report_and_favorite(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = CaseActivityPage(driver) + activity.case_activity_save_report() + +@pytest.mark.login +@pytest.mark.reports +def test_case_04_export_to_excel(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = CaseActivityPage(driver) + web_data = activity.export_case_activity_to_excel() + email = EmailVerification(settings) + link = email.get_hyperlink_from_latest_email(UserData.case_report, settings['url']) + activity.compare_ca_with_email(link, web_data) + +@pytest.mark.login +@pytest.mark.reports +def test_case_05_email_report(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = CaseActivityPage(driver) + web_data, subject = activity.export_case_activity_email() + email = EmailVerification(settings) + table_data = email.get_email_body_from_latest_email(subject, settings['url']) + activity.compare_ca_with_html_table(table_data, web_data) + + + +@pytest.mark.login +@pytest.mark.reports +def test_case_06_user_type_date_verification(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = CaseActivityPage(driver) + activity.case_activity_users_active() + activity.case_activity_users_deactivated() + activity.user_data_verify() + + diff --git a/ElasticSearchTests/testCases/test_04_project_performance.py b/ElasticSearchTests/testCases/test_04_project_performance.py new file mode 100644 index 000000000..077d972b4 --- /dev/null +++ b/ElasticSearchTests/testCases/test_04_project_performance.py @@ -0,0 +1,63 @@ +import pytest + +from ElasticSearchTests.testPages.project_performance.project_performance_page import ProjectPerformancePage +from HQSmokeTests.testPages.email.email_verification import EmailVerification +from HQSmokeTests.testPages.home.home_page import HomePage +from HQSmokeTests.testPages.users.org_structure_page import latest_download_file +from ElasticSearchTests.userInputs.user_inputs import UserData +from ElasticSearchTests.testPages.case_activity.case_activity_page import CaseActivityPage + +""""Contains all test cases that aren't specifically related any menu modules""" + + +@pytest.mark.login +@pytest.mark.reports +def test_case_01_project_performance_report_fields_filters_columns(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = ProjectPerformancePage(driver) + activity.verify_proj_perf_page_fields() + activity.hide_filters() + activity.show_filters() + activity.verify_tables_columns() + + +def test_case_02_pagination(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = ProjectPerformancePage(driver) + activity.verify_proj_perf_page_fields() + activity.proj_perf_pagination_list() + activity.verify_pagination_dropdown() + + + +@pytest.mark.login +@pytest.mark.reports +def test_case_03_save_report_and_favorite(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = ProjectPerformancePage(driver) + activity.proj_perf_save_report() + +@pytest.mark.login +@pytest.mark.reports +def test_case_04_multi_option_export_to_excel(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = ProjectPerformancePage(driver) + activity.proj_perf_group_selection() + list_low, list_inactive, list_high = activity.export_proj_perf_to_excel() + activity.compare_pp_with_excel(list_low, list_inactive, list_high) + +@pytest.mark.login +@pytest.mark.reports +def test_case_05_email_report(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = ProjectPerformancePage(driver) + web_data, subject = activity.export_proj_perf_email() + email = EmailVerification(settings) + table_data = email.get_email_body_from_latest_email_proj_perf(subject, settings['url']) + activity.compare_proj_perf_with_html_table(table_data, web_data) + diff --git a/ElasticSearchTests/testCases/test_05_submissions_by_form.py b/ElasticSearchTests/testCases/test_05_submissions_by_form.py new file mode 100644 index 000000000..5531a716f --- /dev/null +++ b/ElasticSearchTests/testCases/test_05_submissions_by_form.py @@ -0,0 +1,90 @@ +import pytest + + +from HQSmokeTests.testPages.email.email_verification import EmailVerification +from HQSmokeTests.testPages.home.home_page import HomePage +from ElasticSearchTests.userInputs.user_inputs import UserData +from ElasticSearchTests.testPages.submissions_by_forms.submissions_by_form_page import SubmissionsByFormPage + +""""Contains all test cases that aren't specifically related any menu modules""" + + +@pytest.mark.login +@pytest.mark.reports +def test_case_01_sub_by_form_report_fields_filters_columns(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = SubmissionsByFormPage(driver) + activity.verify_sub_by_form_page_fields() + activity.hide_filters() + activity.show_filters() + activity.verify_table_columns() + activity.verify_users_in_the_group() + + + +@pytest.mark.login +@pytest.mark.reports +def test_case_02_pagination(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = SubmissionsByFormPage(driver) + activity.sub_by_form_pagination_list() + activity.verify_pagination_dropdown() + activity.verify_sorted_list() + + +@pytest.mark.login +@pytest.mark.reports +def test_case_03_save_report_and_favorite(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = SubmissionsByFormPage(driver) + activity.sub_by_form_save_report() + +@pytest.mark.login +@pytest.mark.reports +def test_case_04_export_to_excel(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = SubmissionsByFormPage(driver) + web_data = activity.export_sub_by_form_to_excel() + activity.compare_sbf_with_email(web_data) + +@pytest.mark.login +@pytest.mark.reports +def test_case_05_email_report(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = SubmissionsByFormPage(driver) + web_data, subject = activity.export_sub_by_form_email() + email = EmailVerification(settings) + table_data = email.get_email_body_from_latest_email(subject, settings['url']) + activity.compare_sbf_with_html_table(table_data, web_data) + +@pytest.mark.login +@pytest.mark.reports +def test_case_06_user_type_filter_by(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = SubmissionsByFormPage(driver) + activity.sub_by_form_users_active() + activity.sub_by_form_users_deactivated() + activity.filter_dates_and_verify(UserData.filter_dates_by[0]) + # activity.filter_dates_and_verify(UserData.filter_dates_by[1]) + +def test_case_07_advanced_options(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = SubmissionsByFormPage(driver) + activity.advanced_options() + activity.form_column_verification(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + activity.form_column_verification(UserData.reassign_cases_application) + activity.form_column_verification(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1]) + activity.form_column_verification(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[0]) + diff --git a/ElasticSearchTests/testCases/test_06_form_completion_time.py b/ElasticSearchTests/testCases/test_06_form_completion_time.py new file mode 100644 index 000000000..6646b2c25 --- /dev/null +++ b/ElasticSearchTests/testCases/test_06_form_completion_time.py @@ -0,0 +1,69 @@ +import pytest + +from HQSmokeTests.testPages.home.home_page import HomePage +from ElasticSearchTests.userInputs.user_inputs import UserData +from ElasticSearchTests.testPages.form_completion_time.form_completion_time_page import FormCompletionTimePage + +""""Contains all test cases that aren't specifically related any menu modules""" + + +@pytest.mark.login +@pytest.mark.reports +def test_case_01_form_comp_time_report_fields_filters_columns(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = FormCompletionTimePage(driver) + activity.verify_form_comp_time_page_fields() + activity.hide_filters() + activity.show_filters() + activity.verify_table_columns() + activity.verify_users_in_the_group() + + + +@pytest.mark.login +@pytest.mark.reports +def test_case_02_pagination(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = FormCompletionTimePage(driver) + activity.form_comp_time_pagination_list() + activity.verify_pagination_dropdown() + activity.verify_sorted_list() + + +@pytest.mark.login +@pytest.mark.reports +def test_case_03_save_report_and_favorite(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = FormCompletionTimePage(driver) + activity.form_comp_time_save_report() + +@pytest.mark.login +@pytest.mark.reports +def test_case_04_export_to_excel(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = FormCompletionTimePage(driver) + web_data = activity.export_form_comp_time_to_excel() + activity.compare_fct_with_email(web_data) + +@pytest.mark.login +@pytest.mark.reports +def test_case_05_user_type_filter_by(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = FormCompletionTimePage(driver) + activity.form_comp_time_users_active() + activity.form_comp_time_users_deactivated() + activity.filter_dates_and_verify(UserData.filter_dates_by[0]) + # Commenting verification for Submission time filter as there is a bug + # activity.filter_dates_and_verify(UserData.filter_dates_by[1]) + +def test_case_06_advanced_options(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = FormCompletionTimePage(driver) + activity.no_form_selected() + activity.advanced_options() diff --git a/ElasticSearchTests/testCases/test_07_form_completion_vs_submission_trends.py b/ElasticSearchTests/testCases/test_07_form_completion_vs_submission_trends.py new file mode 100644 index 000000000..730a883ae --- /dev/null +++ b/ElasticSearchTests/testCases/test_07_form_completion_vs_submission_trends.py @@ -0,0 +1,70 @@ +import pytest + +from HQSmokeTests.testPages.home.home_page import HomePage +from ElasticSearchTests.userInputs.user_inputs import UserData +from ElasticSearchTests.testPages.form_completion_vs_submission_trends.form_completion_vs_submission_trends_page import FormCompletionVsSubmissionTrends + +""""Contains all test cases that aren't specifically related any menu modules""" + + +@pytest.mark.login +@pytest.mark.reports +def test_case_01_form_comp_sub_trends_report_fields_filters_columns(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = FormCompletionVsSubmissionTrends(driver) + activity.verify_form_comp_sub_trends_page_fields() + activity.hide_filters() + activity.show_filters() + activity.verify_table_columns() + activity.form_comp_sub_trends_users_active() + + +@pytest.mark.login +@pytest.mark.reports +def test_case_02_pagination(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = FormCompletionVsSubmissionTrends(driver) + activity.form_comp_sub_trends_pagination_list() + activity.verify_pagination_dropdown() + activity.verify_sorted_list("User") + activity.verify_sorted_list("Completion Time") + activity.verify_sorted_list("Submission Time") + activity.verify_sorted_list("Form Name") + activity.verify_sorted_list("Difference") + + +@pytest.mark.login +@pytest.mark.reports +def test_case_03_save_report_and_favorite(driver, settings): + report = HomePage(driver, settings) + report.reports_menu() + activity = FormCompletionVsSubmissionTrends(driver) + activity.form_comp_sub_trends_save_report() + activity.save_report_error() + +@pytest.mark.login +@pytest.mark.reports +def test_case_04_export_to_excel(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = FormCompletionVsSubmissionTrends(driver) + web_data = activity.export_form_comp_sub_trends_to_excel() + activity.compare_fct_with_email(web_data) + + +def test_case_06_advanced_options(driver, settings): + home = HomePage(driver, settings) + home.reports_menu() + activity = FormCompletionVsSubmissionTrends(driver) + activity.advanced_options() + activity.form_column_verification(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + activity.form_column_verification(UserData.reassign_cases_application) + activity.form_column_verification(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1]) + activity.form_column_verification(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[0]) diff --git a/ElasticSearchTests/testPages/__init__.py b/ElasticSearchTests/testPages/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/case_activity/__init__.py b/ElasticSearchTests/testPages/case_activity/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/case_activity/case_activity_page.py b/ElasticSearchTests/testPages/case_activity/case_activity_page.py new file mode 100644 index 000000000..11061ec64 --- /dev/null +++ b/ElasticSearchTests/testPages/case_activity/case_activity_page.py @@ -0,0 +1,845 @@ +import html +import os +import time + +import dateutil.relativedelta +import pandas as pd + +from datetime import datetime, timedelta, date +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from selenium.webdriver import ActionChains + +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from ElasticSearchTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec + +""""Contains test page elements and functions related to the Reports module""" + + +class CaseActivityPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.case_activity_rep = (By.LINK_TEXT, "Case Activity") + self.case_activity_TITLE = "Case Activity - CommCare HQ" + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + self.homepage = (By.XPATH, ".//a[@href='/homepage/']") + self.date_range_error = (By.XPATH, "//td[contains(.,'You are limited to a span of 90 days,')]") + + self.form_activity_results = (By.XPATH, "//table[@id='report_table_case_activity']/tbody/tr") + self.form_activity_results_cells = (By.XPATH, "//table[@id='report_table_case_activity']/tbody/tr/td") + self.users_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.user_from_list = "//li[contains(.,'{}')]" + self.case_type_dropdown = (By.XPATH, "//select[@id='report_filter_case_type']") + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + self.user_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_case_activity']/div[contains(.,'User')])[1]") + self.active_cases_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_case_activity']/div[contains(.,'# Active Cases')])[1]") + self.inactive_cases_column = ( + By.XPATH, + "(//thead/tr/th[@aria-controls='report_table_case_activity']/div[contains(.,'# Inactive Cases')])[1]") + + self.users_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.users_list = (By.XPATH, "//ul[contains(@class,'select2-results__options')]/li") + self.users_list_empty = ( + By.XPATH, "//ul[contains(@id,'select2-emw-bi-results')]/li[.='The results could not be loaded.']") + + self.column_names = "(//thead/tr/th[@aria-controls='report_table_case_activity']/div[@data-title='{}'])[{}]" + self.column_group_names = "(//thead/tr/th//strong[.='{}'])[1]" + self.user_names_column_list = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[1]") + self.last_submission_column_list = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[4]") + self.result_table = (By.XPATH, "(//div[@id='report-content']//table//tbody//td[1])[1]") + self.results_rows = (By.XPATH, "//tbody/tr") + self.result_rows_names = "//tbody/tr/td[1][contains(.,'{}')]" + self.all_users_row_names = (By.XPATH, "//tfoot/td[contains(.,'All Users')]") + self.hide_filters_options = (By.XPATH, "//a[.='Hide Filter Options']") + self.show_filters_options = (By.XPATH, "//a[.='Show Filter Options']") + self.user_sort = ( + By.XPATH, "(//text()[contains(.,'User')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]") + self.user_sort_asc = (By.XPATH, "//th[contains(@aria-label,'Users')][contains(@class,'headerSortAsc')]//i") + self.active_cases_column_list = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[7]") + self.total_cases_shared_column_list = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[8]") + self.column_name_headers = "//table[@id='report_table_case_activity']//thead//th/div/div[contains(.,'{}')]" + + + # Pagination + self.page_list_dropdown = (By.XPATH, "//select[@name='report_table_case_activity_length']") + self.table_info = (By.XPATH, "//div[@id='report_table_case_activity_info']") + self.prev_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='prev']/a") + self.next_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='next']/a") + self.prev_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='prev disabled']/a") + self.next_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='next disabled']/a") + self.page_button = "//ul[@class='pagination']/li/a[.='{}']" + self.pagination_list = (By.XPATH, "//ul[@class='pagination']/li/a") + + # Custom date selector + self.from_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='monthselect']") + self.from_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='yearselect']") + self.from_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + + self.to_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='monthselect']") + self.to_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='yearselect']") + self.to_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + self.apply_date = ( + By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Apply']") + self.remove_active_worker = (By.XPATH, + "//span[.='[Active Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_deactive_worker = (By.XPATH, + "//span[.='[Deactivated Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + + # Save Report and Favorites + self.favorite_button = (By.XPATH, "//button[contains(.,'Favorites')]") + self.empty_fav_list = (By.XPATH, '//a[.="You don\'t have any favorites"]') + self.saved_fav = "//a[contains(.,'{}')][contains(@data-bind,'text: name')]" + self.save_config_button = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.name_field = (By.XPATH, "//input[@data-bind='value: name']") + self.description_field = (By.XPATH, "//textarea[@data-bind='value: description']") + self.date_range_field_select = (By.XPATH, "//select[@data-bind='value: date_range']") + self.save_report_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Save']") + self.try_again_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Try Again']") + self.report_save_error = (By.XPATH, "//div[.='Some required fields are missing. Please complete them before saving.']") + self.cancel_report_button = (By.XPATH, "//div/a[.='Cancel']") + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = "//a[text()='{}']" + self.delete_saved = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + + # Case Type Verify + self.case_created_column = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[5]//a") + self.case_created_title = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[5]//span") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr/td[1]") + self.case_list_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Case List')]") + self.case_list_table_info = (By.XPATH, "//div[@id='report_table_case_list_info']") + self.case_list_page_dropdown = (By.XPATH, "//select[@name='report_table_case_list_length']") + self.owner_column_list = (By.XPATH, "//tbody//td[3]") + self.empty_table = (By.XPATH, "//tr/td[contains(.,'No data available to display.')]") + + # Email report + self.email_report_btn = (By.XPATH, "//a[@id='email-report']") + self.email_subject_field = (By.XPATH, "//input[@id='id_subject']") + self.email_form_cancel_btn = (By.XPATH, "//input[@id='button-id-close']") + self.send_email_btn = (By.XPATH, "//input[@id='submit-id-submit_btn']") + self.email_success_message = (By.XPATH, "//*[.='Report successfully emailed']") + self.additional_recipients = (By.XPATH, "//textarea[contains(@aria-describedby,'id_recipient_emails')]") + self.reports_notes_field = (By.XPATH, "//textarea[@data-bind='value: notes']") + + + + + + def hide_filters(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.hide_filters_options) + self.click(self.hide_filters_options) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_field, 10), "User field is still present" + assert not self.is_visible_and_displayed(self.case_type_dropdown, 10), "Case Type dropdown is still present" + assert self.is_present(self.show_filters_options), "Show Filters Options is not present" + print("All filters are hidden!") + + def show_filters(self): + self.wait_for_element(self.show_filters_options) + self.click(self.show_filters_options) + time.sleep(2) + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.case_type_dropdown), "Case Type dropdown is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_case_activity_page_fields(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Case Activity page." + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.case_type_dropdown), "Case Type dropdown is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_table_columns(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Case Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.user_column), "User Column not present" + assert self.is_present(self.active_cases_column), "Active Cases Column not present" + assert self.is_present(self.inactive_cases_column), "Inactive Cases Column not present" + for item in UserData.ca_column_group_names: + assert self.is_visible_and_displayed((By.XPATH, self.column_group_names.format(item))), "Column not present" + print(item, " is present!") + + for item in UserData.ca_column_names: + assert self.is_visible_and_displayed( + (By.XPATH, self.column_names.format(item, 1))), " Column " + item + "for first group not present" + assert self.is_visible_and_displayed( + (By.XPATH, self.column_names.format(item, 2))), " Column " + item + "for second group not present" + assert self.is_visible_and_displayed( + (By.XPATH, self.column_names.format(item, 3))), " Column " + item + "for third group not present" + print(item, " is present for all 3 groups!") + assert self.is_present(self.all_users_row_names), "All Users row is not present" + + + def verify_user_lookup_table(self): + self.wait_to_click(self.users_field) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_list_empty, 10), "Case Type List is not empty" + list = self.find_elements(self.users_list) + print(len(list)) + assert int(len(list)) >= 1 + print("A Look up for Case type is successfully loaded") + + def date_generator(self, start, end): + start_date = parse(start) + end_date = parse(end) # perhaps date.now() + date_list = [] + delta = end_date - start_date # returns timedelta + + for i in range(delta.days + 1): + day = start_date + timedelta(days=i) + day = str(day.strftime('%Y-%m-%d')) + date_list.append(day) + print(day) + return date_list + + + def remove_default_users(self): + self.wait_for_element(self.users_field) + count = self.find_elements(self.remove_buttons) + print(len(count)) + for i in range(len(count)): + count[0].click() + time.sleep(2) + if len(count) != 1: + ActionChains(self.driver).send_keys(Keys.TAB).perform() + time.sleep(2) + count = self.find_elements(self.remove_buttons) + + def verify_date_column_name_headers(self, date_list): + print(len(date_list)) + print(date_list) + if len(date_list)>0: + for item in date_list: + assert self.is_present((By.XPATH, self.column_name_headers.format(item))), "Date "+ item +" not present" + print("Column for date "+ item+ " is present in the table") + + + def verify_users_in_the_group(self): + list = self.find_elements(self.results_rows) + if len(list) > 0: + for item in UserData.automation_group_users: + assert self.is_present((By.XPATH, self.result_rows_names.format( + item))), "Group user " + item + " is not present in results." + print("Group User " + item + " is present in results.") + + + def case_activity_pagination_list(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Case Activity page." + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + pages = self.find_elements(self.pagination_list) + pages_count = len(pages) - 2 + print("Total Pages: ", pages_count) + first_page = pages[1].text + last_page = pages[-2].text + if pages_count > 1: + assert self.is_present(self.prev_page_button_disabled), "Previous button is not disabled." + print("Previous button disabled correctly") + print("Clicking on page " + last_page) + self.wait_to_click((By.XPATH, self.page_button.format(last_page))) + time.sleep(15) + assert self.is_present(self.next_page_button_disabled), "Next button is not disabled." + print("Next button disabled correctly") + time.sleep(5) + print("Clicking on page " + first_page) + self.wait_to_click((By.XPATH, self.page_button.format(first_page))) + time.sleep(15) + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + self.wait_to_click(self.next_page_button) + time.sleep(10) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print(list1_names, list2_names) + assert list1_names != list2_names, "Both Pages have same values" + print("Next button functioning correctly.") + self.wait_to_click(self.prev_page_button) + time.sleep(5) + list3 = self.find_elements(self.user_names_column_list) + list3_names = list() + for item in list3: + list3_names.append(item.text) + print(list1_names, list2_names, list3_names) + assert list1_names == list3_names and list2_names != list3_names, "Page contains same data as the previous" + print("Prev button functioning correctly.") + else: + print("Not enough users are present.") + assert self.is_present(self.prev_page_button_disabled) + assert self.is_present(self.next_page_button_disabled) + print("Both Previous and Next Page buttons are disabled correctly.") + + def verify_pagination_dropdown(self): + info = self.get_text(self.table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + + for item in UserData.pagination: + self.select_by_value(self.page_list_dropdown, item) + time.sleep(10) + list = self.find_elements(self.user_names_column_list) + print(len(list)) + if int(info[-2]) < int(item): + assert int(len(list)) == int(info[-2]), "List does not have all records." + print("Records displayed correctly for " + item) + elif int(info[-2]) >= int(item): + assert int(len(list)) == int(item), "List does not have all records." + print("Records displayed correctly for " + item) + else: + print("No records to display") + + def verify_sorted_list(self): + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + self.scroll_to_element(self.user_sort) + self.click(self.user_sort) + time.sleep(10) + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + sorted_list = sorted(list1_names) + assert list1_names == sorted_list, "List is not sorted" + rev_list = list(reversed(sorted_list)) + print("List is in ascending order", list1_names) + self.scroll_to_element(self.user_sort) + self.click(self.user_sort) + time.sleep(15) + print("Reversed list: ", rev_list) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print("New List: ", list2_names) + assert list2_names == rev_list, "List is not reversed" + print("List is in descending order") + + def value_date_range_7_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return str(week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), week_ago.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_30_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + pastday = presentday - timedelta(30) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_last_month(self): + last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) + start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) + print(start_day_of_prev_month, last_day_of_prev_month) + return str(start_day_of_prev_month.strftime('%Y-%m-%d') + " to " + last_day_of_prev_month.strftime( + '%Y-%m-%d')), start_day_of_prev_month.strftime( + '%Y-%m-%d'), last_day_of_prev_month.strftime('%Y-%m-%d') + + def case_activity_search(self, date_range=UserData.date_range[0]): + date_string = start_date = end_date = '' + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not theCase Activity page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(date_range))) + text = self.get_attribute(self.date_input, "value") + print(text) + if date_range == UserData.date_range[0]: + date_string, start_date, end_date = self.value_date_range_7_days() + elif date_range == UserData.date_range[1]: + date_string, start_date, end_date = self.value_date_range_last_month() + elif date_range == UserData.date_range[2]: + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + date_range) + + def date_validator(self, date_value, start_date, end_date): + dt = parse(date_value) + st = parse(start_date) + et = parse(end_date) + print(dt, st, et) + if st <= dt <= et: + assert True, "Date outside date range" + print("within range") + else: + print("not within range") + assert False + + def case_activity_search_custom_date(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not theCase Activity page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 5) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string+Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present_and_displayed(self.date_range_error), "Date Range Error not displayed" + print("Date Range error correctly displayed") + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not theCase Activity page." + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.select_date_from_picker(start_date, end_date) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[3]) + + + def get_custom_dates_past(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + pastday = presentday - relativedelta(days=days, months=months, years=years) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def get_custom_dates_future(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + futureday = presentday + relativedelta(days=days, months=months, years=years) + return str(presentday.strftime('%Y-%m-%d') + " to " + futureday.strftime('%Y-%m-%d')), presentday.strftime( + '%Y-%m-%d'), futureday.strftime('%Y-%m-%d') + + def select_date_from_picker(self, start_date, end_date): + start_date = parse(start_date) + start_day = str(start_date.day) + start_month = str(start_date.month - 1) + start_year = str(start_date.year) + end_date = parse(end_date) + end_day = str(end_date.day) + end_month = str(end_date.month - 1) + end_year = str(end_date.year) + self.wait_for_element(self.from_month) + self.select_by_value(self.from_year, start_year) + time.sleep(2) + self.select_by_value(self.from_month, start_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.from_date.format(start_day))) + time.sleep(2) + self.wait_for_element(self.to_month) + self.select_by_value(self.to_year, end_year) + time.sleep(2) + self.select_by_value(self.to_month, end_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.to_date.format(end_day))) + time.sleep(2) + self.wait_to_click(self.apply_date) + + def case_activity_save_report(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + time.sleep(10) + report_name = "Saved Case Activity Report " + fetch_random_string() + self.verify_favorite_empty(report_name) + self.save_report_donot_save(report_name) + self.save_report(report_name) + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + self.verify_favorite_created(report_name) + time.sleep(10) + self.verify_users_in_the_group() + self.delete_saved_report(report_name) + self.wait_to_click(self.case_activity_rep) + self.verify_favorite_empty(report_name) + + def verify_favorite_empty(self, report=None): + self.wait_to_click(self.favorite_button) + if report==None: + assert self.is_visible_and_displayed(self.empty_fav_list), "Favorites Already Present" + else: + assert not self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report)),30), "Favorite is already Present" + print("No Favorites yet.") + + def verify_favorite_created(self, report): + self.wait_to_click(self.favorite_button) + assert not self.is_visible_and_displayed(self.empty_fav_list, 10), "Favorites Already Present" + assert self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report))), "Favorite Not Present" + print("Favorites added.") + self.wait_to_click((By.XPATH, self.saved_fav.format(report))) + + def delete_saved_report(self, report): + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 120) + print("Report Present!") + self.click((By.XPATH, self.delete_saved.format(report))) + print("Deleted Saved Report") + time.sleep(5) + self.driver.refresh() + assert not self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 20) + print("Deleted Report Successfully") + + def save_report_donot_save(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.wait_to_clear_and_send_keys(self.name_field, report_name) + self.wait_to_click(self.cancel_report_button) + time.sleep(2) + assert not self.is_visible_and_displayed(self.name_field, 10), "Save Report Form not closed" + print("Save Report Form is closed") + + def save_report(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.clear(self.name_field) + self.wait_to_click(self.save_report_button) + time.sleep(3) + assert self.is_present(self.report_save_error), "Error not displayed" + print("Error is correctly displayed") + self.wait_to_clear_and_send_keys(self.name_field, report_name) + self.wait_to_click(self.try_again_button) + time.sleep(2) + self.driver.refresh() + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report_name)), 120) + print("Report Saved successfully!") + print("Report name: ", report_name) + return report_name + + def verify_case_type_data(self): + case_type_list = self.find_elements(self.case_created_column) + if len(case_type_list) > 0: + for item in case_type_list: + text = item.text + print("Cases created ", text) + if text == '0': + print("No Cases were created withing the given range") + else: + self.wait_to_click(item) + self.switch_to_next_tab() + time.sleep(10) + self.wait_for_element(self.case_list_table_title, 200) + self.scroll_to_bottom() + info = self.get_text(self.case_list_table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert info[-2] == text, "Case created count mismatch" + print("Cases created count matched") + self.select_by_value(self.case_list_page_dropdown, '100') + time.sleep(10) + cases = self.find_elements(self.case_list_table) + if len(cases) > 0: + for case in cases: + name = case.text + assert name == UserData.case_reassign, "Case Type mismatch" + print("Case Type matching") + time.sleep(2) + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def export_case_activity_to_excel(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + self.wait_to_click(self.export_to_excel) + self.wait_for_element(self.export_success) + print("Export to excel successful") + print("Sleeping for some time for the email to be sent") + time.sleep(30) + return list + + def compare_ca_with_email(self, link, web_data): + print(link) + print(web_data) + self.driver.get(link) + time.sleep(10) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + print(new_data.values) + ext_list = [] + ext_list.extend(new_data.values.tolist()) + list = [] + for i in range(len(ext_list) - 1)[1:]: + list += ext_list[i] + print("List New: ", list) + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def export_case_activity_email(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not theCase Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + subject = UserData.email_case_report + self.email_report_form_not_save(subject) + self.email_report_form(subject) + print("Export to excel successful") + print("Sleeping for some time for the email to be sent") + time.sleep(30) + return list, subject + + def email_report_form_not_save(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + assert self.is_present(self.additional_recipients), "Additional recipients field is not present" + print("Additional recipients field is present") + assert self.is_present(self.reports_notes_field), "Report notes field is not present" + print("Report notes field is present") + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.email_form_cancel_btn) + print("Email report form closed properly") + + def email_report_form(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + assert self.is_present(self.additional_recipients), "Additional recipients field is not present" + print("Additional recipients field is present") + assert self.is_present(self.reports_notes_field), "Report notes field is not present" + print("Report notes field is present") + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.send_email_btn) + assert self.is_visible_and_displayed(self.email_success_message), "Email report not sent successfully" + print("Email report sent successfully") + + def compare_ca_with_html_table(self, table_data, web_data): + list = table_data + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Email Body and Searched results do not match" + print("Both Email Body and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def case_activity_users_active(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_active_worker) + assert not self.is_present(self.remove_active_worker), "Active Mobile Worker is still not removed" + print("Active Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[0]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[0]))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert not self.is_present((By.XPATH, self.result_rows_names.format(UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is present in the active worker list." + print("All Active users are present") + + + + def case_activity_users_deactivated(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_deactive_worker) + assert not self.is_present(self.remove_deactive_worker), "Deactivated Mobile Worker is still not removed" + print("Deactivated Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[1]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[1]))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert self.is_present((By.XPATH, self.result_rows_names.format(UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is not present in the Deactivated worker list." + print("All Deactivated users are present") + + def user_data_verify(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in UserData.automation_group_users: + self.wait_to_click((By.PARTIAL_LINK_TEXT, items)) + time.sleep(15) + self.wait_for_element(self.case_list_table_title) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + time.sleep(2) + owner_list = self.find_elements(self.owner_column_list) + print(len(owner_list)) + if len(owner_list)>1: + for owner in owner_list: + text = owner.text + assert items in text or text in UserData.user_group, "Owner does not match" + print("Owner matching") + time.sleep(5) + self.driver.back() + time.sleep(2) + self.driver.back() + + + diff --git a/ElasticSearchTests/testPages/daily_form_activity/__init__.py b/ElasticSearchTests/testPages/daily_form_activity/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/daily_form_activity/daily_form_activity_page.py b/ElasticSearchTests/testPages/daily_form_activity/daily_form_activity_page.py new file mode 100644 index 000000000..a6b7b9025 --- /dev/null +++ b/ElasticSearchTests/testPages/daily_form_activity/daily_form_activity_page.py @@ -0,0 +1,904 @@ +import html +import os +import time + +import dateutil.relativedelta +import pandas as pd + +from datetime import datetime, timedelta, date +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from selenium.webdriver import ActionChains + +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from ElasticSearchTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec + +""""Contains test page elements and functions related to the Reports module""" + + +class DailyFormActivityPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.daily_form_activity_rep = (By.LINK_TEXT, "Daily Form Activity") + self.DAILY_FORM_ACTIVITY_TITLE = "Daily Form Activity - CommCare HQ" + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + self.homepage = (By.XPATH, ".//a[@href='/homepage/']") + self.date_range_error = (By.XPATH, "//td[contains(.,'You are limited to a span of 90 days,')]") + + self.form_activity_results = (By.XPATH, "//table[@id='report_table_daily_form_stats']/tbody/tr") + self.form_activity_results_cells = (By.XPATH, "//table[@id='report_table_daily_form_stats']/tbody/tr/td") + self.users_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.filter_dates_by = (By.XPATH, "//select[@id='report_filter_sub_time']") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.user_from_list = "//li[contains(.,'{}')]" + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + self.user_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_daily_form_stats']/div[contains(.,'Username')])[1]") + self.group_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_daily_form_stats']/div[contains(.,'Group')])[1]") + self.total_column = (By.XPATH, "(//thead/tr/th[@aria-controls='report_table_daily_form_stats']/div[contains(.,'Total')])[1]") + self.users_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.users_list = (By.XPATH, "//ul[contains(@class,'select2-results__options')]/li") + self.users_list_empty = ( + By.XPATH, "//ul[contains(@id,'select2-emw-bi-results')]/li[.='The results could not be loaded.']") + + self.date_input = (By.XPATH, "//input[@id='filter_range']") + self.date_range_type = "//li[@data-range-key='{}']" + self.column_names = "(//thead/tr/th[@aria-controls='report_table_daily_form_stats']/div[@data-title='{}'])[1]" + self.column_group_names = "(//thead/tr/th//strong[.='{}'])[1]" + self.user_names_column_list = (By.XPATH, "//table[@id='report_table_daily_form_stats']//tbody//td[1]") + self.last_submission_column_list = (By.XPATH, "//table[@id='report_table_daily_form_stats']//tbody//td[4]") + self.result_table = (By.XPATH, "(//div[@id='report-content']//table//tbody//td[1])[1]") + self.results_rows = (By.XPATH, "//tbody/tr") + self.result_rows_names = "//tbody/tr/td[1][contains(.,'{}')]" + self.hide_filters_options = (By.XPATH, "//a[.='Hide Filter Options']") + self.show_filters_options = (By.XPATH, "//a[.='Show Filter Options']") + self.user_sort = ( + By.XPATH, "(//text()[contains(.,'User')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]") + self.active_cases_column_list = (By.XPATH, "//table[@id='report_table_daily_form_stats']//tbody//td[7]") + self.total_cases_shared_column_list = (By.XPATH, "//table[@id='report_table_daily_form_stats']//tbody//td[8]") + self.column_name_headers = "//table[@id='report_table_daily_form_stats']//thead//th/div/div[contains(.,'{}')]" + + + # Pagination + self.page_list_dropdown = (By.XPATH, "//select[@name='report_table_daily_form_stats_length']") + self.table_info = (By.XPATH, "//div[@id='report_table_daily_form_stats_info']") + self.prev_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='prev']/a") + self.next_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='next']/a") + self.prev_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='prev disabled']/a") + self.next_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='next disabled']/a") + self.page_button = "//ul[@class='pagination']/li/a[.='{}']" + self.pagination_list = (By.XPATH, "//ul[@class='pagination']/li/a") + + # Custom date selector + self.from_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='monthselect']") + self.from_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='yearselect']") + self.from_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + + self.to_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='monthselect']") + self.to_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='yearselect']") + self.to_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + self.apply_date = ( + By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Apply']") + self.remove_active_worker = (By.XPATH, + "//span[.='[Active Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_deactive_worker = (By.XPATH, + "//span[.='[Deactivated Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + + # Save Report and Favorites + self.favorite_button = (By.XPATH, "//button[contains(.,'Favorites')]") + self.empty_fav_list = (By.XPATH, '//a[.="You don\'t have any favorites"]') + self.saved_fav = "//a[contains(.,'{}')][contains(@data-bind,'text: name')]" + self.save_config_button = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.name_field = (By.XPATH, "//input[@data-bind='value: name']") + self.description_field = (By.XPATH, "//textarea[@data-bind='value: description']") + self.date_range_field_select = (By.XPATH, "//select[@data-bind='value: date_range']") + self.save_report_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Save']") + self.try_again_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Try Again']") + self.report_save_error = (By.XPATH, "//div[.='Some required fields are missing. Please complete them before saving.']") + self.cancel_report_button = (By.XPATH, "//div/a[.='Cancel']") + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = "//a[text()='{}']" + self.delete_saved = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + + # Case Type Verify + self.case_created_column = (By.XPATH, "//table[@id='report_table_daily_form_stats']//tbody//td[5]//a") + self.case_created_title = (By.XPATH, "//table[@id='report_table_daily_form_stats']//tbody//td[5]//span") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr/td[1]") + self.case_list_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Case List')]") + self.case_list_table_info = (By.XPATH, "//div[@id='report_table_case_list_info']") + self.case_list_page_dropdown = (By.XPATH, "//select[@name='report_table_case_list_length']") + + # Email report + self.email_report_btn = (By.XPATH, "//a[@id='email-report']") + self.email_subject_field = (By.XPATH, "//input[@id='id_subject']") + self.email_form_cancel_btn = (By.XPATH, "//input[@id='button-id-close']") + self.send_email_btn = (By.XPATH, "//input[@id='submit-id-submit_btn']") + self.email_success_message = (By.XPATH, "//*[.='Report successfully emailed']") + + # Submit History Verification + self.total_form_counts = "//td[contains(.,'{}')]//following-sibling::td[last()]" + self.filter_column_name = "(//thead//th[@aria-controls='report_table_submit_history'][3]/div[contains(.,'{}')])[1]" + self.submit_history_table_info = (By.XPATH, "//div[@id='report_table_submit_history_info']") + self.empty_table = (By.XPATH, "//tr/td[contains(.,'No data available to display.')]") + self.submit_history_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Submit History')]") + + + def hide_filters(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.hide_filters_options) + self.click(self.hide_filters_options) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_field, 10), "User field is still present" + assert not self.is_visible_and_displayed(self.date_input, 10), "Date Range field is still present" + assert not self.is_visible_and_displayed(self.filter_dates_by, 10), "Filter Dates By field is still present" + assert self.is_present(self.show_filters_options), "Show Filters Options is not present" + print("All filters are hidden!") + + def show_filters(self): + self.wait_for_element(self.show_filters_options) + self.click(self.show_filters_options) + time.sleep(2) + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.filter_dates_by), "Filter Dates By field is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_daily_activity_page_fields(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Daily Form Activity page." + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.filter_dates_by), "Filter Dates By field is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_table_columns(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Daily Form Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_7_days() + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.user_column), "Username Column not present" + assert self.is_present(self.total_column), "Total Column not present" + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + + def verify_user_lookup_table(self): + self.wait_to_click(self.users_field) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_list_empty, 10), "Case Type List is not empty" + list = self.find_elements(self.users_list) + print(len(list)) + assert int(len(list)) >= 1 + print("A Look up for Case type is successfully loaded") + + def date_generator(self, start, end): + start_date = parse(start) + end_date = parse(end) # perhaps date.now() + date_list = [] + delta = end_date - start_date # returns timedelta + + for i in range(delta.days + 1): + day = start_date + timedelta(days=i) + day = str(day.strftime('%Y-%m-%d')) + date_list.append(day) + print(day) + return date_list + + + def remove_default_users(self): + self.wait_for_element(self.users_field) + count = self.find_elements(self.remove_buttons) + print(len(count)) + for i in range(len(count)): + count[0].click() + time.sleep(2) + if len(count) != 1: + ActionChains(self.driver).send_keys(Keys.TAB).perform() + time.sleep(2) + count = self.find_elements(self.remove_buttons) + + def verify_date_column_name_headers(self, date_list): + print(len(date_list)) + print(date_list) + if len(date_list)>0: + for item in date_list: + assert self.is_present((By.XPATH, self.column_name_headers.format(item))), "Date "+ item +" not present" + print("Column for date "+ item+ " is present in the table") + + + def verify_users_in_the_group(self): + list = self.find_elements(self.results_rows) + if len(list) > 0: + for item in UserData.automation_group_users: + assert self.is_present((By.XPATH, self.result_rows_names.format( + item))), "Group user " + item + " is not present in results." + print("Group User " + item + " is present in results.") + + + def daily_form_activity_pagination_list(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + pages = self.find_elements(self.pagination_list) + pages_count = len(pages) - 2 + print("Total Pages: ", pages_count) + first_page = pages[1].text + last_page = pages[-2].text + if pages_count > 1: + assert self.is_present(self.prev_page_button_disabled), "Previous button is not disabled." + print("Previous button disabled correctly") + print("Clicking on page " + last_page) + self.wait_to_click((By.XPATH, self.page_button.format(last_page))) + time.sleep(15) + assert self.is_present(self.next_page_button_disabled), "Next button is not disabled." + print("Next button disabled correctly") + time.sleep(5) + print("Clicking on page " + first_page) + self.wait_to_click((By.XPATH, self.page_button.format(first_page))) + time.sleep(15) + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + self.wait_to_click(self.next_page_button) + time.sleep(5) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print(list1_names, list2_names) + assert list1_names != list2_names, "Both Pages have same values" + print("Next button functioning correctly.") + self.wait_to_click(self.prev_page_button) + time.sleep(5) + list3 = self.find_elements(self.user_names_column_list) + list3_names = list() + for item in list3: + list3_names.append(item.text) + print(list1_names, list2_names, list3_names) + assert list1_names == list3_names and list2_names != list3_names, "Page contains same data as the previous" + print("Prev button functioning correctly.") + else: + print("Not enough users are present.") + assert self.is_present(self.prev_page_button_disabled) + assert self.is_present(self.next_page_button_disabled) + print("Both Previous and Next Page buttons are disabled correctly.") + + def verify_pagination_dropdown(self): + info = self.get_text(self.table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + + for item in UserData.pagination: + self.select_by_value(self.page_list_dropdown, item) + time.sleep(10) + list = self.find_elements(self.user_names_column_list) + print(len(list)) + if int(info[-2]) < int(item): + assert int(len(list)) == int(info[-2]), "List does not have all records." + print("Records displayed correctly for " + item) + elif int(info[-2]) >= int(item): + assert int(len(list)) == int(item), "List does not have all records." + print("Records displayed correctly for " + item) + else: + print("No records to display") + + def verify_sorted_list(self): + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + sorted_list = sorted(list1_names) + assert list1_names == sorted_list, "List is not sorted" + print("List is in ascending order") + self.wait_to_click(self.user_sort) + time.sleep(15) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + rev_list = sorted(list1_names, reverse=True) + assert list2_names == rev_list, "List is not sorted" + print("List is in descending order") + + def value_date_range_7_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return str(week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), week_ago.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_30_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + pastday = presentday - timedelta(30) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_last_month(self): + last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) + start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) + print(start_day_of_prev_month, last_day_of_prev_month) + return str(start_day_of_prev_month.strftime('%Y-%m-%d') + " to " + last_day_of_prev_month.strftime( + '%Y-%m-%d')), start_day_of_prev_month.strftime( + '%Y-%m-%d'), last_day_of_prev_month.strftime('%Y-%m-%d') + + def daily_form_activity_search(self, date_range=UserData.date_range[0]): + date_string = start_date = end_date = '' + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Daily Form Activity page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(date_range))) + text = self.get_attribute(self.date_input, "value") + print(text) + if date_range == UserData.date_range[0]: + date_string, start_date, end_date = self.value_date_range_7_days() + elif date_range == UserData.date_range[1]: + date_string, start_date, end_date = self.value_date_range_last_month() + elif date_range == UserData.date_range[2]: + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + date_range) + + def date_validator(self, date_value, start_date, end_date): + dt = parse(date_value) + st = parse(start_date) + et = parse(end_date) + print(dt, st, et) + if st <= dt <= et: + assert True, "Date outside date range" + print("within range") + else: + print("not within range") + assert False + + def daily_form_activity_search_custom_date(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Daily Form Activity page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 5) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string+Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present_and_displayed(self.date_range_error), "Date Range Error not displayed" + print("Date Range error correctly displayed") + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Daily Form Activity page." + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.select_date_from_picker(start_date, end_date) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[3]) + + + def get_custom_dates_past(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + pastday = presentday - relativedelta(days=days, months=months, years=years) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def get_custom_dates_future(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + futureday = presentday + relativedelta(days=days, months=months, years=years) + return str(presentday.strftime('%Y-%m-%d') + " to " + futureday.strftime('%Y-%m-%d')), presentday.strftime( + '%Y-%m-%d'), futureday.strftime('%Y-%m-%d') + + def select_date_from_picker(self, start_date, end_date): + start_date = parse(start_date) + start_day = str(start_date.day) + start_month = str(start_date.month - 1) + start_year = str(start_date.year) + end_date = parse(end_date) + end_day = str(end_date.day) + end_month = str(end_date.month - 1) + end_year = str(end_date.year) + self.wait_for_element(self.from_month) + self.select_by_value(self.from_year, start_year) + time.sleep(2) + self.select_by_value(self.from_month, start_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.from_date.format(start_day))) + time.sleep(2) + self.wait_for_element(self.to_month) + self.select_by_value(self.to_year, end_year) + time.sleep(2) + self.select_by_value(self.to_month, end_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.to_date.format(end_day))) + time.sleep(2) + self.wait_to_click(self.apply_date) + + def daily_form_activity_save_report(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_7_days() + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[0]) + time.sleep(10) + self.verify_favorite_empty() + self.save_report_donot_save() + report = self.save_report() + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + self.verify_favorite_created(report) + time.sleep(10) + self.verify_users_in_the_group() + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[0]) + self.delete_saved_report(report) + self.wait_to_click(self.daily_form_activity_rep) + self.verify_favorite_empty() + + def verify_favorite_empty(self): + self.wait_to_click(self.favorite_button) + assert self.is_visible_and_displayed(self.empty_fav_list), "Favorites Already Present" + print("No Favorites yet.") + + def verify_favorite_created(self, report): + self.wait_to_click(self.favorite_button) + assert not self.is_visible_and_displayed(self.empty_fav_list, 10), "Favorites Already Present" + assert self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report))), "Favorite Not Present" + print("Favorites added.") + self.wait_to_click((By.XPATH, self.saved_fav.format(report))) + + def delete_saved_report(self, report): + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 120) + print("Report Present!") + self.click((By.XPATH, self.delete_saved.format(report))) + print("Deleted Saved Report") + time.sleep(5) + self.driver.refresh() + assert not self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 20) + print("Deleted Report Successfully") + + def save_report_donot_save(self): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + report_name = "Saved Daily Form Activity Report " + fetch_random_string() + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.cancel_report_button) + time.sleep(2) + assert not self.is_visible_and_displayed(self.name_field, 10), "Save Report Form not closed" + print("Save Report Form is closed") + + def save_report(self): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + report_name = "Saved Daily Form Activity Report " + fetch_random_string() + self.clear(self.name_field) + self.wait_to_click(self.save_report_button) + time.sleep(3) + assert self.is_present(self.report_save_error), "Error not displayed" + print("Error is correctly displayed") + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.try_again_button) + time.sleep(2) + self.driver.refresh() + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report_name)), 120) + print("Report Saved successfully!") + print("Report name: ", report_name) + return report_name + + def verify_case_type_data(self): + case_type_list = self.find_elements(self.case_created_column) + if len(case_type_list) > 0: + for item in case_type_list: + text = item.text + print("Cases created ", text) + if text == '0': + print("No Cases were created withing the given range") + else: + self.wait_to_click(item) + self.switch_to_next_tab() + time.sleep(10) + self.wait_for_element(self.case_list_table_title, 200) + self.scroll_to_bottom() + info = self.get_text(self.case_list_table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert info[-2] == text, "Case created count mismatch" + print("Cases created count matched") + self.select_by_value(self.case_list_page_dropdown, '100') + time.sleep(10) + cases = self.find_elements(self.case_list_table) + if len(cases) > 0: + for case in cases: + name = case.text + assert name == UserData.case_reassign, "Case Type mismatch" + print("Case Type matching") + time.sleep(2) + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def export_daily_form_activity_to_excel(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + self.wait_to_click(self.export_to_excel) + self.wait_for_element(self.export_success) + print("Export to excel successful") + print("Sleeping for some time for the email to be sent") + time.sleep(30) + return list + + def compare_dfa_with_email(self, link, web_data): + print(link) + print(web_data) + self.driver.get(link) + time.sleep(10) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + print(new_data.values) + ext_list = [] + ext_list.extend(new_data.values.tolist()) + list = [] + for i in range(len(ext_list) - 1)[:]: + list += ext_list[i] + print("List New: ", list) + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def export_daily_form_activity_email(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Daily Form Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + subject = UserData.email_daily_form_report + self.email_report_form_not_save(subject) + self.email_report_form(subject) + print("Export to excel successful") + print("Sleeping for some time for the email to be sent") + time.sleep(30) + return list, subject + + def email_report_form_not_save(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.email_form_cancel_btn) + print("Email report form closed properly") + + def email_report_form(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.send_email_btn) + assert self.is_visible_and_displayed(self.email_success_message), "Email report not sent successfully" + print("Email report sent successfully") + + def compare_dfa_with_html_table(self, table_data, web_data): + list = table_data + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Email Body and Searched results do not match" + print("Both Email Body and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def daily_form_activity_users_active(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_active_worker) + assert not self.is_present(self.remove_active_worker), "Active Mobile Worker is still not removed" + print("Active Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[0]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[0]))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert not self.is_present((By.XPATH, self.result_rows_names.format(UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is present in the active worker list." + print("All Active users are present") + + + + def daily_form_activity_users_deactivated(self): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_deactive_worker) + assert not self.is_present(self.remove_deactive_worker), "Deactivated Mobile Worker is still not removed" + print("Deactivated Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[1]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[1]))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert self.is_present((By.XPATH, self.result_rows_names.format(UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is not present in the Deactivated worker list." + print("All Deactivated users are present") + + + def verify_assigned_cases_count(self, actives, totals): + print("Sleeping for some time for the cases to be assigned") + time.sleep(60) + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + active_cases = self.find_elements(self.active_cases_column_list) + actives_new = [] + for items in active_cases: + actives_new.append(items.text) + total_cases = self.find_elements(self.total_cases_shared_column_list) + totals_new = [] + for items in total_cases: + totals_new.append(items.text) + print("Active Case: ", actives_new) + print("Total shared case: ", totals_new) + for i in range(len(actives_new)): + assert int(actives[i])-10 == actives_new[i], "Active Cases not reduced" + print("Active cases reduced") + for i in range(len(totals_new)): + assert int(totals[i])-10 == totals_new[i], "Active Cases not reduced" + print("Active cases reduced") + print("Cases successfully assigned") + + def filter_dates_and_verify(self, filter): + self.wait_to_click(self.daily_form_activity_rep) + self.wait_for_element(self.apply_id) + assert self.DAILY_FORM_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, filter) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + date_string = self.get_attribute(self.date_input, "value") + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in UserData.automation_group_users: + count = self.get_text((By.XPATH, self.total_form_counts.format(items))) + print(count) + self.wait_to_click((By.PARTIAL_LINK_TEXT, items)) + time.sleep(15) + self.wait_for_element(self.submit_history_table_title) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + assert filter == self.get_selected_text(self.filter_dates_by), "Date Filter mismatched" + print("Date Filter matched") + assert date_string == self.get_attribute(self.date_input, "value"), "Date Range mismatched" + print("Date Range matched") + assert self.is_present((By.XPATH, self.filter_column_name.format(filter))), "Incorrect column present" + print("Correct Column present") + self.scroll_to_bottom() + time.sleep(2) + info = self.get_text(self.submit_history_table_info) + print(info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert count == info[-2], "Form counts not matching" + print("Form Count matching") + if count == '0': + assert self.is_present(self.empty_table) + print("Correct value displayed") + time.sleep(5) + self.driver.back() + + + diff --git a/ElasticSearchTests/testPages/data/__init__.py b/ElasticSearchTests/testPages/data/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/data/reassign_cases_page.py b/ElasticSearchTests/testPages/data/reassign_cases_page.py new file mode 100644 index 000000000..aa8083843 --- /dev/null +++ b/ElasticSearchTests/testPages/data/reassign_cases_page.py @@ -0,0 +1,85 @@ +import time + +from selenium.webdriver import ActionChains +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By + +from HQSmokeTests.testPages.data.copy_cases_page import CopyCasesPage +from common_utilities.selenium.base_page import BasePage +from ElasticSearchTests.userInputs.user_inputs import UserData + +""""Contains test page elements and functions related to the Reassign Cases module""" + + +class ReassignCasesPage(BasePage): + + def __init__(self, driver, settings): + super().__init__(driver) + self.settings = settings + + self.env_url = settings["url"] + self.reassign_cases_menu = (By.LINK_TEXT, "Reassign Cases") + self.apply = (By.ID, "apply-btn") + self.case_type = (By.ID, "report_filter_case_type") + self.case_owner_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.user_from_list = "//li[contains(.,'{}')]" + self.remove_project_data = (By.XPATH, + "//span[.='[Project Data]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + + + self.case_type_option_value = (By.XPATH, "//option[@value='reassign']") + self.select_all = (By.XPATH, "(//a[@class='select-all btn btn-xs btn-default'][.='all'])[1]") + self.select_first_case = (By.XPATH, "(//input[@type='checkbox'])[2]") + self.first_case_name = (By.XPATH, "(//a[contains(@class, 'ajax_dialog')])[1]") + self.user_search_dropdown = (By.ID, "select2-reassign_owner_select-container") + self.user_to_be_reassigned = (By.XPATH, "(//li[contains(.,'Active Mobile Worker')])[1]") + + self.submit = (By.XPATH, "(//button[text()='Reassign'])[1]") + self.new_owner_name = (By.XPATH, "((//td)[4])[1]") + self.out_of_range = (By.XPATH, "(//span[@class='label label-warning'])[1]") + self.search_query = (By.ID, "report_filter_search_query") + self.reassign_to_user_dropdwon_input = (By.XPATH, "//input[@class='select2-search__field']") + self.reassigned_user_from_list = "//li[starts-with(text(), '{}') and contains(text(), 'Active Mobile Worker')]" + + self.last_modified = (By.XPATH, "(//text()[contains(.,'Last Modified')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]") + self.last_modified_ascending = (By.XPATH, "(//text()[contains(.,'Last Modified')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]//parent::div//parent::th[@aria-sort='ascending']") + self.last_modified_descending = (By.XPATH, "(//text()[contains(.,'Last Modified')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]//parent::div//parent::th[@aria-sort='descending']") + + def get_cases(self, text): + self.wait_to_click(self.reassign_cases_menu) + self.wait_for_element(self.case_owner_field) + self.wait_to_click(self.remove_project_data) + self.send_keys(self.case_owner_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group_shared))) + time.sleep(2) + ActionChains(self.driver).send_keys(Keys.TAB).perform() + self.send_keys(self.search_query, text) + self.wait_to_click(self.apply) + print("Sleeping for the list to load") + time.sleep(20) + + def reassign_case(self, text): + self.get_cases(text) + copy = CopyCasesPage(self.driver, self.settings) + copy.sort_for_latest_on_top() + time.sleep(5) + self.wait_to_click(self.select_all) + self.wait_to_click(self.user_search_dropdown) + self.send_keys(self.reassign_to_user_dropdwon_input, UserData.assign_case_user) + assigned_username = self.get_text((By.XPATH, self.reassigned_user_from_list.format(UserData.assign_case_user))) + print("Assigned Username:", assigned_username) + self.move_to_element_and_click((By.XPATH, self.reassigned_user_from_list.format(UserData.assign_case_user))) + self.wait_to_click(self.submit) + time.sleep(20) + self.is_visible_and_displayed(self.out_of_range) + print("Sleeping sometime for the case to get updated") + time.sleep(10) + self.driver.refresh() + print("Cases reassigned") + + def sort_for_latest_on_top(self): + self.wait_to_click(self.last_modified) + self.wait_for_element(self.last_modified_ascending, 50) + time.sleep(5) + self.wait_to_click(self.last_modified) + self.wait_for_element(self.last_modified_descending, 50) \ No newline at end of file diff --git a/ElasticSearchTests/testPages/form_completion_time/__init__.py b/ElasticSearchTests/testPages/form_completion_time/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/form_completion_time/form_completion_time_page.py b/ElasticSearchTests/testPages/form_completion_time/form_completion_time_page.py new file mode 100644 index 000000000..0cbb91b4d --- /dev/null +++ b/ElasticSearchTests/testPages/form_completion_time/form_completion_time_page.py @@ -0,0 +1,1156 @@ +import html +import os +import time + +import dateutil.relativedelta +import pandas as pd + +from datetime import datetime, timedelta, date +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from selenium.webdriver import ActionChains + +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from ElasticSearchTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec + +""""Contains test page elements and functions related to the Reports module""" + + +class FormCompletionTimePage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.form_comp_time_rep = (By.LINK_TEXT, "Form Completion Time") + self.form_comp_time_TITLE = "Form Completion Time - CommCare HQ" + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + self.no_form_selected_msg = (By.XPATH, "(//thead//tr//div[contains(.,'No Form Selected')])[1]") + self.homepage = (By.XPATH, ".//a[@href='/homepage/']") + self.date_range_error = (By.XPATH, "//td[contains(.,'You are limited to a span of 90 days,')]") + + self.form_activity_results = (By.XPATH, "//table[@id='report_table_completion_times']/tbody/tr") + self.form_activity_results_cells = ( + By.XPATH, "//table[@id='report_table_completion_times']/tbody/tr[not(contains(.,'All Users'))]/td") + self.all_users_results_cells = ( + By.XPATH, "(//tfoot)[2]/tr/td") + self.users_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.filter_dates_by = (By.XPATH, "//select[@id='report_filter_sub_time']") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.user_from_list = "//li[contains(.,'{}')]" + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + self.user_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_completion_times']/div[contains(.,'User')])[1]") + self.all_forms_column = ( + By.XPATH, + "(//thead/tr/th[@aria-controls='report_table_completion_times']/div[contains(.,'All Forms')])[1]") + self.column_names = "(//thead/tr/th[@aria-controls='report_table_completion_times']/div[contains(.,'{}')])[1]" + self.users_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.users_list = (By.XPATH, "//ul[contains(@class,'select2-results__options')]/li") + self.users_list_empty = ( + By.XPATH, "//ul[contains(@id,'select2-emw-bi-results')]/li[.='The results could not be loaded.']") + + self.date_input = (By.XPATH, "//input[@id='filter_range']") + self.date_range_type = "//li[@data-range-key='{}']" + self.column_group_names = "(//thead/tr/th//strong[.='{}'])[1]" + self.user_names_column_list = (By.XPATH, "//table[@id='report_table_completion_times']//tbody//td[1]") + self.last_submission_column_list = (By.XPATH, "//table[@id='report_table_completion_times']//tbody//td[4]") + self.result_table = (By.XPATH, "(//div[@id='report-content']//table//tbody//td[1])[1]") + self.results_rows = (By.XPATH, "//tbody/tr") + self.result_rows_names = "//table[@id='report_table_completion_times']//tbody/tr/td[1]//a[contains(.,'{}')]" + self.hide_filters_options = (By.XPATH, "//a[.='Hide Filter Options']") + self.show_filters_options = (By.XPATH, "//a[.='Show Filter Options']") + self.user_sort = ( + By.XPATH, "(//text()[contains(.,'User')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]") + self.active_cases_column_list = (By.XPATH, "//table[@id='report_table_completion_times']//tbody//td[7]") + self.total_cases_shared_column_list = ( + By.XPATH, "//table[@id='report_table_completion_times']//tbody//td[8]") + self.column_name_headers = "//table[@id='report_table_completion_times']//thead//th/div/div[contains(.,'{}')]" + + # Pagination + self.page_list_dropdown = (By.XPATH, "//select[@name='report_table_completion_times_length']") + self.table_info = (By.XPATH, "//div[@id='report_table_completion_times_info']") + self.prev_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='prev']/a") + self.next_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='next']/a") + self.prev_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='prev disabled']/a") + self.next_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='next disabled']/a") + self.page_button = "//ul[@class='pagination']/li/a[.='{}']" + self.pagination_list = (By.XPATH, "//ul[@class='pagination']/li/a") + + # Custom date selector + self.from_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='monthselect']") + self.from_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='yearselect']") + self.from_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + + self.to_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='monthselect']") + self.to_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='yearselect']") + self.to_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + self.apply_date = ( + By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Apply']") + self.remove_active_worker = (By.XPATH, + "//span[.='[Active Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_deactive_worker = (By.XPATH, + "//span[.='[Deactivated Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + + # Save Report and Favorites + self.favorite_button = (By.XPATH, "//button[contains(.,'Favorites')]") + self.empty_fav_list = (By.XPATH, '//a[.="You don\'t have any favorites"]') + self.saved_fav = "//a[contains(.,'{}')][contains(@data-bind,'text: name')]" + self.save_config_button = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.name_field = (By.XPATH, "//input[@data-bind='value: name']") + self.description_field = (By.XPATH, "//textarea[@data-bind='value: description']") + self.date_range_field_select = (By.XPATH, "//select[@data-bind='value: date_range']") + self.save_report_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Save']") + self.try_again_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Try Again']") + self.report_save_error = ( + By.XPATH, "//div[.='Some required fields are missing. Please complete them before saving.']") + self.cancel_report_button = (By.XPATH, "//div/a[.='Cancel']") + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = "//a[text()='{}']" + self.delete_saved = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + + # Case Type Verify + self.case_created_column = (By.XPATH, "//table[@id='report_table_completion_times']//tbody//td[5]//a") + self.case_created_title = (By.XPATH, "//table[@id='report_table_completion_times']//tbody//td[5]//span") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr/td[1]") + self.case_list_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Case List')]") + self.case_list_table_info = (By.XPATH, "//div[@id='report_table_case_list_info']") + self.case_list_page_dropdown = (By.XPATH, "//select[@name='report_table_case_list_length']") + + # Email report + self.email_report_btn = (By.XPATH, "//a[@id='email-report']") + self.email_subject_field = (By.XPATH, "//input[@id='id_subject']") + self.email_form_cancel_btn = (By.XPATH, "//input[@id='button-id-close']") + self.send_email_btn = (By.XPATH, "//input[@id='submit-id-submit_btn']") + self.email_success_message = (By.XPATH, "//*[.='Report successfully emailed']") + + # Application form section + self.application_dropdown = (By.XPATH, "//select[@id='report_filter_form_app_id']") + self.module_dropdown = (By.XPATH, "//select[@id='report_filter_form_module']") + self.form_dropdown = (By.XPATH, "//select[@id='report_filter_form_xmlns']") + self.show_adv_options = (By.XPATH, "//input[@name='show_advanced']") + self.known_forms = (By.XPATH, "//input[@id='report_filter_form_unknown_hide']") + self.unknown_forms = (By.XPATH, "//input[@id='report_filter_form_unknown_show']") + self.unknown_form_dropdown = (By.XPATH, "//select[@id='report_filter_form-unknown_xmlns']") + self.application_type_dropdown = (By.XPATH, "//select[@id='report_filter_form_status']") + + # Submit History Verification + self.total_form_counts = "//td[contains(.,'{}')]//following-sibling::td[last()]" + self.filter_column_name = "(//thead//th[@aria-controls='report_table_submit_history'][3]/div[contains(.,'{}')])[1]" + self.submit_history_table_info = (By.XPATH, "//div[@id='report_table_submit_history_info']") + self.empty_table = (By.XPATH, "//tr/td[contains(.,'No data available to display.')]") + self.submit_history_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Submit History')]") + + def hide_filters(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.hide_filters_options) + self.click(self.hide_filters_options) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_field, 10), "User field is still present" + assert not self.is_visible_and_displayed(self.application_dropdown, 10), "Application dropdown is still present" + assert not self.is_visible_and_displayed(self.show_adv_options, + 10), "Show Advance Options checkbox is still present" + assert not self.is_visible_and_displayed(self.date_input, 10), "Date Range field is still present" + assert not self.is_visible_and_displayed(self.filter_dates_by, 10), "Filter Dates By field is still present" + assert self.is_present(self.show_filters_options), "Show Filters Options is not present" + print("All filters are hidden!") + + def show_filters(self): + self.wait_for_element(self.show_filters_options) + self.click(self.show_filters_options) + time.sleep(2) + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + assert self.is_present(self.show_adv_options), "Show Advance Options checkbox is not present" + assert self.is_present(self.filter_dates_by), "Filter Dates By field is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_form_comp_time_page_fields(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Form Completion Time page." + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + assert self.is_present(self.show_adv_options), "Show Advance Options checkbox is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.filter_dates_by), "Filter Dates By field is not present" + list_opt = self.get_all_dropdown_options(self.filter_dates_by) + assert list_opt == list(UserData.filter_dates_by), "Filter dates bu options are not matching" + self.wait_to_click(self.date_input) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[1]))) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_table_columns(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Form Completion Time page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.user_column), "Username Column not present" + for item in UserData.fct_column_names: + assert self.is_present((By.XPATH, self.column_names.format(item))), "Column not present: " + item + + def select_application_and_forms(self, app, module, form): + self.wait_for_element(self.application_dropdown) + text = self.get_selected_text(self.application_dropdown) + print(text) + assert UserData.default_app_mod_form_fct[0] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form_fct[0] + print(UserData.default_app_mod_form_fct[0] + " is present as default value") + self.select_by_text(self.application_dropdown, app) + self.wait_for_element(self.module_dropdown) + text = self.get_selected_text(self.module_dropdown) + print(text) + assert UserData.default_app_mod_form_fct[1] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form_fct[1] + print(UserData.default_app_mod_form_fct[1] + " is present as default value") + mod_list = [UserData.default_app_mod_form_fct[1]] + list(UserData.reasign_modules_forms.keys()) + self.verify_dropdown_options(self.module_dropdown, mod_list) + self.select_by_text(self.module_dropdown, module) + self.wait_for_element(self.form_dropdown) + text = self.get_selected_text(self.form_dropdown) + print(text) + assert UserData.default_app_mod_form_fct[2] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form_fct[2] + print(UserData.default_app_mod_form_fct[2] + " is present as default value") + form_list = [UserData.default_app_mod_form_fct[2]] + UserData.reasign_modules_forms[module] + self.verify_dropdown_options(self.form_dropdown, form_list) + self.select_by_text(self.form_dropdown, form) + + def verify_dropdown_options(self, locator, list_to_compare): + print("List to compare: ", list_to_compare) + assert list_to_compare == self.get_all_dropdown_options(locator), "Dropdown does not have all the options" + print("All module/form options are present in the dropdown") + + def verify_user_lookup_table(self): + self.wait_to_click(self.users_field) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_list_empty, 10), "User List is not empty" + list = self.find_elements(self.users_list) + print(len(list)) + assert int(len(list)) >= 1 + print("A Look up for users is successfully loaded") + + def date_generator(self, start, end): + start_date = parse(start) + end_date = parse(end) # perhaps date.now() + date_list = [] + delta = end_date - start_date # returns timedelta + + for i in range(delta.days + 1): + day = start_date + timedelta(days=i) + day = str(day.strftime('%Y-%m-%d')) + date_list.append(day) + print(day) + return date_list + + def remove_default_users(self): + self.wait_for_element(self.users_field) + count = self.find_elements(self.remove_buttons) + print(len(count)) + for i in range(len(count)): + count[0].click() + time.sleep(2) + if len(count) != 1: + ActionChains(self.driver).send_keys(Keys.TAB).perform() + time.sleep(2) + count = self.find_elements(self.remove_buttons) + + def verify_users_in_the_group(self): + list = self.find_elements(self.results_rows) + if len(list) > 0: + for item in UserData.automation_group_users: + assert self.is_present((By.XPATH, self.result_rows_names.format( + item))), "Group user " + item + " is not present in results." + print("Group User " + item + " is present in results.") + + def form_comp_time_pagination_list(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + pages = self.find_elements(self.pagination_list) + pages_count = len(pages) - 2 + print("Total Pages: ", pages_count) + first_page = pages[1].text + last_page = pages[-2].text + if pages_count > 1: + assert self.is_present(self.prev_page_button_disabled), "Previous button is not disabled." + print("Previous button disabled correctly") + print("Clicking on page " + last_page) + self.wait_to_click((By.XPATH, self.page_button.format(last_page))) + time.sleep(15) + assert self.is_present(self.next_page_button_disabled), "Next button is not disabled." + print("Next button disabled correctly") + time.sleep(5) + print("Clicking on page " + first_page) + self.wait_to_click((By.XPATH, self.page_button.format(first_page))) + time.sleep(15) + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + self.wait_to_click(self.next_page_button) + time.sleep(5) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print(list1_names, list2_names) + assert list1_names != list2_names, "Both Pages have same values" + print("Next button functioning correctly.") + self.wait_to_click(self.prev_page_button) + time.sleep(5) + list3 = self.find_elements(self.user_names_column_list) + list3_names = list() + for item in list3: + list3_names.append(item.text) + print(list1_names, list2_names, list3_names) + assert list1_names == list3_names and list2_names != list3_names, "Page contains same data as the previous" + print("Prev button functioning correctly.") + else: + print("Not enough users are present.") + assert self.is_present(self.prev_page_button_disabled) + assert self.is_present(self.next_page_button_disabled) + print("Both Previous and Next Page buttons are disabled correctly.") + + def verify_pagination_dropdown(self): + info = self.get_text(self.table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + + for item in UserData.pagination: + self.select_by_value(self.page_list_dropdown, item) + time.sleep(10) + list = self.find_elements(self.user_names_column_list) + print(len(list)) + if int(info[-2]) < int(item): + assert int(len(list)) == int(info[-2]), "List does not have all records." + print("Records displayed correctly for " + item) + elif int(info[-2]) >= int(item): + assert int(len(list)) == int(item), "List does not have all records." + print("Records displayed correctly for " + item) + else: + print("No records to display") + + def verify_sorted_list(self): + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + sorted_list = sorted(list1_names) + assert list1_names == sorted_list, "List is not sorted" + print("List is in ascending order") + self.wait_to_click(self.user_sort) + time.sleep(15) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + rev_list = list(reversed(sorted_list)) + assert list2_names == rev_list, "List is not sorted" + print("List is in descending order") + + def value_date_range_7_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return str(week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), week_ago.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_30_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + pastday = presentday - timedelta(30) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_last_month(self): + last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) + start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) + print(start_day_of_prev_month, last_day_of_prev_month) + return str(start_day_of_prev_month.strftime('%Y-%m-%d') + " to " + last_day_of_prev_month.strftime( + '%Y-%m-%d')), start_day_of_prev_month.strftime( + '%Y-%m-%d'), last_day_of_prev_month.strftime('%Y-%m-%d') + + def form_comp_time_search(self, date_range=UserData.date_range[0]): + date_string = start_date = end_date = '' + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Form Completion Time page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(date_range))) + text = self.get_attribute(self.date_input, "value") + print(text) + if date_range == UserData.date_range[0]: + date_string, start_date, end_date = self.value_date_range_7_days() + elif date_range == UserData.date_range[1]: + date_string, start_date, end_date = self.value_date_range_last_month() + elif date_range == UserData.date_range[2]: + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + date_range) + + def date_validator(self, date_value, start_date, end_date): + dt = parse(date_value) + st = parse(start_date) + et = parse(end_date) + print(dt, st, et) + if st <= dt <= et: + assert True, "Date outside date range" + print("within range") + else: + print("not within range") + assert False + + def form_comp_time_search_custom_date(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Form Completion Time page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 5) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string + Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present_and_displayed(self.date_range_error), "Date Range Error not displayed" + print("Date Range error correctly displayed") + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Form Completion Time page." + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.select_date_from_picker(start_date, end_date) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[3]) + + def get_custom_dates_past(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + pastday = presentday - relativedelta(days=days, months=months, years=years) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def get_custom_dates_future(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + futureday = presentday + relativedelta(days=days, months=months, years=years) + return str(presentday.strftime('%Y-%m-%d') + " to " + futureday.strftime('%Y-%m-%d')), presentday.strftime( + '%Y-%m-%d'), futureday.strftime('%Y-%m-%d') + + def select_date_from_picker(self, start_date, end_date): + start_date = parse(start_date) + start_day = str(start_date.day) + start_month = str(start_date.month - 1) + start_year = str(start_date.year) + end_date = parse(end_date) + end_day = str(end_date.day) + end_month = str(end_date.month - 1) + end_year = str(end_date.year) + self.wait_for_element(self.from_month) + self.select_by_value(self.from_year, start_year) + time.sleep(2) + self.select_by_value(self.from_month, start_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.from_date.format(start_day))) + time.sleep(2) + self.wait_for_element(self.to_month) + self.select_by_value(self.to_year, end_year) + time.sleep(2) + self.select_by_value(self.to_month, end_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.to_date.format(end_day))) + time.sleep(2) + self.wait_to_click(self.apply_date) + + def form_comp_time_save_report(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_7_days() + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + time.sleep(10) + report_name = "Saved Form Completion Time Report " + fetch_random_string() + self.verify_favorite_empty(report_name) + self.save_report_donot_save(report_name) + report = self.save_report(report_name) + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + self.verify_favorite_created(report) + time.sleep(10) + self.verify_users_in_the_group() + self.delete_saved_report(report) + self.wait_to_click(self.form_comp_time_rep) + self.verify_favorite_empty(report_name) + + def verify_favorite_empty(self, report=None): + self.wait_to_click(self.favorite_button) + if report == None: + assert self.is_visible_and_displayed(self.empty_fav_list), "Favorites Already Present" + else: + assert not self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report)), + 30), "Favorite is already Present" + print("No Favorites yet.") + + def verify_favorite_created(self, report): + self.wait_to_click(self.favorite_button) + assert not self.is_visible_and_displayed(self.empty_fav_list, 10), "Favorites Already Present" + assert self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report))), "Favorite Not Present" + print("Favorites added.") + self.wait_to_click((By.XPATH, self.saved_fav.format(report))) + + def delete_saved_report(self, report): + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 120) + print("Report Present!") + self.click((By.XPATH, self.delete_saved.format(report))) + print("Deleted Saved Report") + time.sleep(5) + self.driver.refresh() + assert not self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 20) + print("Deleted Report Successfully") + + def save_report_donot_save(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.cancel_report_button) + time.sleep(2) + assert not self.is_visible_and_displayed(self.name_field, 10), "Save Report Form not closed" + print("Save Report Form is closed") + + def save_report(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.clear(self.name_field) + self.wait_to_click(self.save_report_button) + time.sleep(3) + assert self.is_present(self.report_save_error), "Error not displayed" + print("Error is correctly displayed") + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.try_again_button) + time.sleep(2) + self.driver.refresh() + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report_name)), 120) + print("Report Saved successfully!") + print("Report name: ", report_name) + return report_name + + def verify_case_type_data(self): + case_type_list = self.find_elements(self.case_created_column) + if len(case_type_list) > 0: + for item in case_type_list: + text = item.text + print("Cases created ", text) + if text == '0': + print("No Cases were created withing the given range") + else: + self.wait_to_click(item) + self.switch_to_next_tab() + time.sleep(10) + self.wait_for_element(self.case_list_table_title, 200) + self.scroll_to_bottom() + info = self.get_text(self.case_list_table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert info[-2] == text, "Case created count mismatch" + print("Cases created count matched") + self.select_by_value(self.case_list_page_dropdown, '100') + time.sleep(10) + cases = self.find_elements(self.case_list_table) + if len(cases) > 0: + for case in cases: + name = case.text + assert name == UserData.case_reassign, "Case Type mismatch" + print("Case Type matching") + time.sleep(2) + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def export_form_comp_time_to_excel(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + # self.verify_user_lookup_table() + # self.remove_default_users() + # self.send_keys(self.users_field, UserData.user_group) + # self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + # time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(15) + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list_col = [] + for c in col: + list_col.append(c.text) + print(list_col) + self.wait_to_click(self.export_to_excel) + print("Export to excel successful") + print("sleeping for sometime for the download to complete") + time.sleep(15) + return list_col + + def compare_fct_with_email(self, web_data): + print(web_data) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + print(new_data.values) + ext_list = [] + ext_list.extend(new_data.values.tolist()) + list = [] + for i in range(len(ext_list) - 1)[:]: + list += ext_list[i] + print("List New: ", list) + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + if ":" in str(list[i]): + text = str(list[i]).split(':') + text = str(int(text[0]) * 3600 + int(text[1]) * 60 + int(text[2])) + " seconds" + print("Comparing ", text, " with ", str(web_data[i])) + if text == "0 seconds": + assert str(web_data[i]) == "", "Comparison failed for " + list[i] + " and " + web_data[i] + else: + assert text == str(web_data[i]) or text in str(web_data[i]), "Comparison failed for " + list[i] + " and " + web_data[i] + else: + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]) or html.unescape(str(list[i])) in str(web_data[i]), "Comparison failed for " + list[i] + " and " + web_data[i] + + def export_form_comp_time_email(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Form Completion Time page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list_col = [] + for c in col: + list_col.append(c.text) + print(list_col) + footer = self.find_elements(self.all_users_results_cells) + list_ft = [] + for f in footer: + list_ft.append(f.text) + print(list_ft) + list_col.extend(list_ft) + subject = UserData.email_form_comp_report + self.email_report_form_not_save(subject) + self.email_report_form(subject) + print("Export to excel successful") + + return list_col, subject + + def email_report_form_not_save(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.email_form_cancel_btn) + print("Email report form closed properly") + + def email_report_form(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.send_email_btn) + assert self.is_visible_and_displayed(self.email_success_message), "Email report not sent successfully" + print("Email report sent successfully") + + def compare_fct_with_html_table(self, table_data, web_data): + list = table_data + print("Table data rows: ", len(web_data), "Web data rows: ", len(list)) + print("Table List: ", web_data) + print("Web list: ", list) + assert len(web_data) == len(list), "Data in Both Email Body and Searched results do not match" + print("Both Email Body and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def form_comp_time_users_active(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_active_worker) + assert not self.is_present(self.remove_active_worker), "Active Mobile Worker is still not removed" + print("Active Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[0]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[0]))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert not self.is_present((By.XPATH, self.result_rows_names.format( + UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is present in the active worker list." + print("All Active users are present") + + def form_comp_time_users_deactivated(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_deactive_worker) + assert not self.is_present(self.remove_deactive_worker), "Deactivated Mobile Worker is still not removed" + print("Deactivated Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[1]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[1]))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert self.is_present((By.XPATH, self.result_rows_names.format( + UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is not present in the Deactivated worker list." + print("All Deactivated users are present") + + def verify_assigned_cases_count(self, actives, totals): + print("Sleeping for some time for the cases to be assigned") + time.sleep(60) + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + active_cases = self.find_elements(self.active_cases_column_list) + actives_new = [] + for items in active_cases: + actives_new.append(items.text) + total_cases = self.find_elements(self.total_cases_shared_column_list) + totals_new = [] + for items in total_cases: + totals_new.append(items.text) + print("Active Case: ", actives_new) + print("Total shared case: ", totals_new) + for i in range(len(actives_new)): + assert int(actives[i]) - 10 == actives_new[i], "Active Cases not reduced" + print("Active cases reduced") + for i in range(len(totals_new)): + assert int(totals[i]) - 10 == totals_new[i], "Active Cases not reduced" + print("Active cases reduced") + print("Cases successfully assigned") + + def filter_dates_and_verify(self, filter): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.select_by_text(self.filter_dates_by, filter) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string + Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in UserData.automation_group_users: + count = self.get_text((By.XPATH, self.total_form_counts.format(items))) + print(count) + time.sleep(1) + self.js_click((By.XPATH, self.result_rows_names.format(items))) + time.sleep(15) + self.wait_for_element(self.submit_history_table_title) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + assert filter == self.get_selected_text(self.filter_dates_by), "Date Filter mismatched" + print("Date Filter matched") + assert UserData.reassign_cases_application == self.get_selected_text( + self.application_dropdown), "Application mismatched" + print("Application matched") + assert list(UserData.reasign_modules_forms.keys())[1] == self.get_selected_text( + self.module_dropdown), "Application mismatched" + print("Application matched") + assert UserData.reasign_modules_forms[list(UserData.reasign_modules_forms.keys())[1]][ + 0] == self.get_selected_text( + self.form_dropdown), "Application mismatched" + print("Application matched") + assert date_string == self.get_attribute(self.date_input, "value"), "Date Range mismatched" + print("Date Range matched") + assert self.is_present((By.XPATH, self.filter_column_name.format(filter))), "Incorrect column present" + print("Correct Column present") + self.scroll_to_bottom() + time.sleep(2) + # info = self.get_text(self.submit_history_table_info) + # print(info) + # info = str(info).split(" ") + # print("Total records: ", info[-2]) + # assert count == info[-2], "Form counts not matching" + # print("Form Count matching") + # if count == '0': + # assert self.is_present(self.empty_table) + # print("Correct value displayed") + time.sleep(5) + self.driver.back() + + def advanced_options(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[0]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[0]))) + time.sleep(1) + self.wait_to_click(self.show_adv_options) + assert self.is_selected(self.show_adv_options), "Show Advanced Options is not selected" + print("Show Advanced Option is successfully selected") + time.sleep(2) + assert self.is_present(self.known_forms), "Known Forms option not present" + assert self.is_present(self.unknown_forms), "Unknown Forms option not present" + assert self.is_present(self.application_type_dropdown), "Application Type dropdown not present" + active_apps, deleted_apps = self.known_forms_options() + self.unknown_forms_options(active_apps, deleted_apps) + self.wait_to_click(self.show_adv_options) + assert not self.is_selected(self.show_adv_options), "Show Advanced Options is still selected" + time.sleep(2) + assert not self.is_visible_and_displayed(self.known_forms, 10), "Known Forms option still present" + assert not self.is_visible_and_displayed(self.unknown_forms, 10), "Unknown Forms option still present" + print("All Show Advanced Options are working correctly") + + def known_forms_options(self): + if not self.is_selected(self.known_forms): + self.wait_to_click(self.known_forms) + assert self.is_selected(self.known_forms), "Known Forms radio button is not selected" + else: + assert self.is_selected(self.known_forms), "Known Forms radio button is not selected" + + self.verify_dropdown_options(self.application_type_dropdown, UserData.fct_app_type_list) + self.select_by_text(self.application_type_dropdown, UserData.fct_app_type_list[0]) + time.sleep(2) + assert not self.is_visible_and_displayed(self.application_dropdown, 10), "Application dropdown is still present" + print("Application dropdown successfully disappeared after selecting option ", UserData.fct_app_type_list[0]) + self.select_by_text(self.application_type_dropdown, UserData.fct_app_type_list[2]) + time.sleep(2) + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + list_app_active = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app_active[1:]: + assert "[Deleted Application]" in items, "Not a Deleted Application option" + print("All Deleted Application present") + self.select_by_text(self.application_type_dropdown, UserData.fct_app_type_list[1]) + time.sleep(2) + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + list_app_deleted = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app_deleted[1:]: + assert "[Deleted Application]" not in items, "Deleted Application is present in the dropdown" + print("No Deleted Application present") + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + print("Correct Modules and Forms are present") + return list_app_active, list_app_deleted + + def unknown_forms_options(self, active, deleted): + if not self.is_selected(self.unknown_forms): + self.wait_to_click(self.unknown_forms) + assert self.is_selected(self.unknown_forms), "Unknown Forms radio button is not selected" + else: + assert self.is_selected(self.unknown_forms), "Unknown Forms radio button is not selected" + + assert self.is_visible_and_displayed(self.unknown_form_dropdown), "Unknown forms dropdown is not present" + print("Application dropdown successfully disappeared after selecting option ", UserData.fct_app_type_list[0]) + list_app = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app[1:]: + assert items not in active or items not in deleted, "Not an Unknown Application option" + print("All Applications present are unknown") + + def generate_form_column_names(self, app, mod=None, forms=None): + column_list = [] + if mod == None and forms == None: + mod = list(UserData.reasign_modules_forms.keys()) + for m in mod: + for f in list(UserData.reasign_modules_forms[m]): + string = app+" > "+m+" > "+f + column_list.append(string) + elif mod !=None and forms == None: + for f in list(UserData.reasign_modules_forms[mod]): + string = app+" > "+mod+" > "+f + column_list.append(string) + else: + string = app + " > " + mod + " > " + forms + column_list.append(string) + print(column_list) + return column_list + + def form_column_verification(self, app, mod=None, form=None): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.application_dropdown, app) + if mod == None and form == None: + column_list = self.generate_form_column_names(app) + self.select_by_text(self.application_dropdown, app) + elif mod != None and form == None: + column_list = self.generate_form_column_names(app, mod) + self.select_by_text(self.application_dropdown, app) + self.select_by_text(self.module_dropdown, mod) + else: + column_list = self.generate_form_column_names(app, mod, form) + self.select_by_text(self.application_dropdown, app) + self.select_by_text(self.module_dropdown, mod) + self.select_by_text(self.form_dropdown, form) + + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in column_list: + assert self.is_present((By.XPATH, self.column_names.format(items))), "Form Name Column not present: " + items + + def no_form_selected(self): + self.wait_to_click(self.form_comp_time_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_time_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + assert self.is_visible_and_displayed(self.no_form_selected_msg), "No form selected message is not displayed." + print("No form selected message is displayed correctly") \ No newline at end of file diff --git a/ElasticSearchTests/testPages/form_completion_vs_submission_trends/__init__.py b/ElasticSearchTests/testPages/form_completion_vs_submission_trends/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/form_completion_vs_submission_trends/form_completion_vs_submission_trends_page.py b/ElasticSearchTests/testPages/form_completion_vs_submission_trends/form_completion_vs_submission_trends_page.py new file mode 100644 index 000000000..30a55b2e7 --- /dev/null +++ b/ElasticSearchTests/testPages/form_completion_vs_submission_trends/form_completion_vs_submission_trends_page.py @@ -0,0 +1,1302 @@ +import html +import os +import time + +import dateutil.relativedelta +import pandas as pd + +from datetime import datetime, timedelta, date +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from selenium.webdriver import ActionChains + +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from ElasticSearchTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec +from natsort import natsorted +""""Contains test page elements and functions related to the Reports module""" + + +class FormCompletionVsSubmissionTrends(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.form_comp_sub_trends_rep = (By.LINK_TEXT, "Form Completion vs. Submission Trends") + self.form_comp_sub_trends_TITLE = "Form Completion vs. Submission Trends - CommCare HQ" + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + self.no_form_selected_msg = (By.XPATH, "(//thead//tr//div[contains(.,'No Form Selected')])[1]") + self.homepage = (By.XPATH, ".//a[@href='/homepage/']") + self.date_range_error = (By.XPATH, "//td[contains(.,'You are limited to a span of 90 days,')]") + + self.form_activity_results = (By.XPATH, "//table[@id='report_table_completion_vs_submission']/tbody/tr") + self.form_activity_results_cells = ( + By.XPATH, "//table[@id='report_table_completion_vs_submission']/tbody/tr[not(contains(.,'All Users'))]/td") + self.all_users_results_cells = ( + By.XPATH, "(//tfoot)[2]/tr/td") + self.users_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.filter_dates_by = (By.XPATH, "//select[@id='report_filter_sub_time']") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.user_from_list = "//li[contains(.,'{}')]" + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + self.user_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_completion_vs_submission']/div[contains(.,'User')])[1]") + self.all_forms_column = ( + By.XPATH, + "(//thead/tr/th[@aria-controls='report_table_completion_vs_submission']/div[contains(.,'All Forms')])[1]") + self.column_names = "(//thead/tr/th[@aria-controls='report_table_completion_vs_submission']/div[contains(.,'{}')])[1]" + self.view_column = (By.XPATH, "(//thead/tr/th/div[contains(.,'View')])[1]") + self.view_form_page = (By.XPATH, "(//table[@id='report_table_completion_vs_submission']//tbody//td[5]/a)[1]") + self.users_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.users_list = (By.XPATH, "//ul[contains(@class,'select2-results__options')]/li") + self.users_list_empty = ( + By.XPATH, "//ul[contains(@id,'select2-emw-bi-results')]/li[.='The results could not be loaded.']") + + self.date_input = (By.XPATH, "//input[@id='filter_range']") + self.date_range_type = "//li[@data-range-key='{}']" + self.column_group_names = "(//thead/tr/th//strong[.='{}'])[1]" + self.user_names_column_list = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[1]") + self.user_names_column_first = (By.XPATH, "(//table[@id='report_table_completion_vs_submission']//tbody//td[1]//a)[1]") + self.completion_column_list = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[2]") + self.submission_column_list = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[3]") + self.form_name_column_list = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[4]") + self.difference_column_list_no_same = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[6][not(contains(.,'same'))]") + self.difference_column_list = ( + By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[6]") + self.last_submission_column_list = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[4]") + self.result_table = (By.XPATH, "(//div[@id='report-content']//table//tbody//td[1])[1]") + self.results_rows = (By.XPATH, "//tbody/tr") + self.result_rows_names = "//table[@id='report_table_completion_vs_submission']//tbody/tr/td[1]//a[contains(.,'{}')]" + self.hide_filters_options = (By.XPATH, "//a[.='Hide Filter Options']") + self.show_filters_options = (By.XPATH, "//a[.='Show Filter Options']") + self.user_sort = "(//text()[contains(.,'{}')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]" + self.active_cases_column_list = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[7]") + self.total_cases_shared_column_list = ( + By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[8]") + self.column_name_headers = "//table[@id='report_table_completion_vs_submission']//thead//th/div/div[contains(.,'{}')]" + + # Pagination + self.page_list_dropdown = (By.XPATH, "//select[@name='report_table_completion_vs_submission_length']") + self.table_info = (By.XPATH, "//div[@id='report_table_completion_vs_submission_info']") + self.prev_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='prev']/a") + self.next_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='next']/a") + self.prev_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='prev disabled']/a") + self.next_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='next disabled']/a") + self.page_button = "//ul[@class='pagination']/li/a[.='{}']" + self.pagination_list = (By.XPATH, "//ul[@class='pagination']/li/a") + + # Custom date selector + self.from_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='monthselect']") + self.from_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='yearselect']") + self.from_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + + self.to_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='monthselect']") + self.to_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='yearselect']") + self.to_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + self.apply_date = ( + By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Apply']") + self.cancel_date = (By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Cancel']") + self.remove_active_worker = (By.XPATH, + "//span[.='[Active Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_deactive_worker = (By.XPATH, + "//span[.='[Deactivated Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + + # Save Report and Favorites + self.favorite_button = (By.XPATH, "//button[contains(.,'Favorites')]") + self.empty_fav_list = (By.XPATH, '//a[.="You don\'t have any favorites"]') + self.saved_fav = "//a[contains(.,'{}')][contains(@data-bind,'text: name')]" + self.save_config_button = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.name_field = (By.XPATH, "//input[@data-bind='value: name']") + self.description_field = (By.XPATH, "//textarea[@data-bind='value: description']") + self.date_range_field_select = (By.XPATH, "//select[@data-bind='value: date_range']") + self.save_report_button = (By.XPATH, "//div[@class='modal-footer']//div/span/div[.='Save']") + self.try_again_button = (By.XPATH, "//span[contains(@id,'save-button')]/div") + self.report_save_error = ( + By.XPATH, "//div[.='Some required fields are missing. Please complete them before saving.']") + self.cancel_report_button = (By.XPATH, "//div/a[.='Cancel']") + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = "//a[text()='{}']" + self.delete_saved = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + + #View Form Page + self.view_form_tabs = "//li/a[contains(.,'{}')]" + self.form_data_table = (By.XPATH, "//table[contains(@class,'form-data-table')]") + + # Case Type Verify + self.case_created_column = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[5]//a") + self.case_created_title = (By.XPATH, "//table[@id='report_table_completion_vs_submission']//tbody//td[5]//span") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr/td[1]") + self.case_list_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Case List')]") + self.case_list_table_info = (By.XPATH, "//div[@id='report_table_case_list_info']") + self.case_list_page_dropdown = (By.XPATH, "//select[@name='report_table_case_list_length']") + + # Email report + self.email_report_btn = (By.XPATH, "//a[@id='email-report']") + self.email_subject_field = (By.XPATH, "//input[@id='id_subject']") + self.email_form_cancel_btn = (By.XPATH, "//input[@id='button-id-close']") + self.send_email_btn = (By.XPATH, "//input[@id='submit-id-submit_btn']") + self.email_success_message = (By.XPATH, "//*[.='Report successfully emailed']") + + # Application form section + self.application_dropdown = (By.XPATH, "//select[@id='report_filter_form_app_id']") + self.module_dropdown = (By.XPATH, "//select[@id='report_filter_form_module']") + self.form_dropdown = (By.XPATH, "//select[@id='report_filter_form_xmlns']") + self.show_adv_options = (By.XPATH, "//input[@name='show_advanced']") + self.known_forms = (By.XPATH, "//input[@id='report_filter_form_unknown_hide']") + self.unknown_forms = (By.XPATH, "//input[@id='report_filter_form_unknown_show']") + self.unknown_form_dropdown = (By.XPATH, "//select[@id='report_filter_form-unknown_xmlns']") + self.application_type_dropdown = (By.XPATH, "//select[@id='report_filter_form_status']") + + # Submit History Verification + self.total_form_counts = "//td[contains(.,'{}')]//following-sibling::td[last()]" + self.filter_column_name = "(//thead//th[@aria-controls='report_table_submit_history'][3]/div[contains(.,'{}')])[1]" + self.submit_history_table_info = (By.XPATH, "//div[@id='report_table_submit_history_info']") + self.empty_table = (By.XPATH, "//tr/td[contains(.,'No data available to display.')]") + self.submit_history_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Submit History')]") + + def hide_filters(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.hide_filters_options) + self.click(self.hide_filters_options) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_field, 10), "User field is still present" + assert not self.is_visible_and_displayed(self.application_dropdown, 10), "Application dropdown is still present" + assert not self.is_visible_and_displayed(self.show_adv_options, + 10), "Show Advance Options checkbox is still present" + assert not self.is_visible_and_displayed(self.date_input, 10), "Date Range field is still present" + assert self.is_present(self.show_filters_options), "Show Filters Options is not present" + print("All filters are hidden!") + + def show_filters(self): + self.wait_for_element(self.show_filters_options) + self.click(self.show_filters_options) + time.sleep(2) + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + assert self.is_present(self.show_adv_options), "Show Advance Options checkbox is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_form_comp_sub_trends_page_fields(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Form Completion vs. Submission Trends page." + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + assert self.is_present(self.show_adv_options), "Show Advance Options checkbox is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + self.wait_to_click(self.date_input) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[1]))) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + assert self.is_present((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + assert self.is_present(self.from_year) + assert self.is_present(self.to_year) + assert self.is_present(self.apply_date) + assert self.is_present(self.cancel_date) + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_table_columns(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Form Completion vs. Submission Trends page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.view_column), "View Column not present" + for item in UserData.fcst_column_names: + assert self.is_present((By.XPATH, self.column_names.format(item))), "Column not present: " + item + print("Column present: ", item) + self.wait_to_click(self.view_form_page) + time.sleep(10) + assert self.is_visible_and_displayed(self.form_data_table, 200), "data Table for user is not present" + for items in UserData.view_form_tabs: + assert self.is_present((By.XPATH, self.view_form_tabs.format(items))), "Tab " +items+ " is not present" + print("View Form page is successfully loaded") + def select_application_and_forms(self, app, module, form): + self.wait_for_element(self.application_dropdown) + text = self.get_selected_text(self.application_dropdown) + print(text) + assert UserData.default_app_mod_form[0] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form[0] + print(UserData.default_app_mod_form[0] + " is present as default value") + self.select_by_text(self.application_dropdown, app) + self.wait_for_element(self.module_dropdown) + text = self.get_selected_text(self.module_dropdown) + print(text) + assert UserData.default_app_mod_form[1] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form[1] + print(UserData.default_app_mod_form[1] + " is present as default value") + mod_list = [UserData.default_app_mod_form[1]] + list(UserData.reasign_modules_forms.keys()) + self.verify_dropdown_options(self.module_dropdown, mod_list) + self.select_by_text(self.module_dropdown, module) + self.wait_for_element(self.form_dropdown) + text = self.get_selected_text(self.form_dropdown) + print(text) + assert UserData.default_app_mod_form[2] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form[2] + print(UserData.default_app_mod_form[2] + " is present as default value") + form_list = [UserData.default_app_mod_form[2]] + UserData.reasign_modules_forms[module] + self.verify_dropdown_options(self.form_dropdown, form_list) + self.select_by_text(self.form_dropdown, form) + + def verify_dropdown_options(self, locator, list_to_compare): + print("List to compare: ", list_to_compare) + assert list_to_compare == self.get_all_dropdown_options(locator), "Dropdown does not have all the options" + print("All module/form options are present in the dropdown") + + def verify_user_lookup_table(self): + self.wait_to_click(self.users_field) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_list_empty, 10), "User List is not empty" + list = self.find_elements(self.users_list) + print(len(list)) + assert int(len(list)) >= 1 + print("A Look up for users is successfully loaded") + + def date_generator(self, start, end): + start_date = parse(start) + end_date = parse(end) # perhaps date.now() + date_list = [] + delta = end_date - start_date # returns timedelta + + for i in range(delta.days + 1): + day = start_date + timedelta(days=i) + day = str(day.strftime('%Y-%m-%d')) + date_list.append(day) + print(day) + return date_list + + def remove_default_users(self): + self.wait_for_element(self.users_field) + count = self.find_elements(self.remove_buttons) + print(len(count)) + for i in range(len(count)): + count[0].click() + time.sleep(2) + if len(count) != 1: + ActionChains(self.driver).send_keys(Keys.TAB).perform() + time.sleep(2) + count = self.find_elements(self.remove_buttons) + + def verify_users_in_the_group(self): + list_user = self.find_elements(self.user_names_column_list) + if len(list_user) > 0: + for item in list_user: + text = item.text + print(text) + assert UserData.automation_group_users[0] in text or UserData.automation_group_users[1] in text, "Selected user " + text + " is not present in the results." + print("Group User " + text + " is present in results.") + + def form_comp_sub_trends_pagination_list(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_7_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + pages = self.find_elements(self.pagination_list) + pages_count = len(pages) - 2 + print("Total Pages: ", pages_count) + first_page = pages[1].text + last_page = pages[-2].text + if pages_count > 1: + assert self.is_present(self.prev_page_button_disabled), "Previous button is not disabled." + print("Previous button disabled correctly") + print("Clicking on page " + last_page) + self.wait_to_click((By.XPATH, self.page_button.format(last_page))) + time.sleep(15) + assert self.is_present(self.next_page_button_disabled), "Next button is not disabled." + print("Next button disabled correctly") + time.sleep(5) + print("Clicking on page " + first_page) + self.wait_to_click((By.XPATH, self.page_button.format(first_page))) + time.sleep(15) + list1 = self.find_elements(self.completion_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + self.wait_to_click(self.next_page_button) + time.sleep(5) + list2 = self.find_elements(self.completion_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print(list1_names, list2_names) + assert list1_names != list2_names, "Both Pages have same values" + print("Next button functioning correctly.") + self.wait_to_click(self.prev_page_button) + time.sleep(5) + list3 = self.find_elements(self.completion_column_list) + list3_names = list() + for item in list3: + list3_names.append(item.text) + print(list1_names, list2_names, list3_names) + assert list1_names == list3_names and list2_names != list3_names, "Page contains same data as the previous" + print("Prev button functioning correctly.") + else: + print("Not enough users are present.") + assert self.is_present(self.prev_page_button_disabled) + assert self.is_present(self.next_page_button_disabled) + print("Both Previous and Next Page buttons are disabled correctly.") + + def verify_pagination_dropdown(self): + info = self.get_text(self.table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + + for item in UserData.pagination: + self.select_by_value(self.page_list_dropdown, item) + time.sleep(10) + list = self.find_elements(self.completion_column_list) + print(len(list)) + if int(info[-2]) < int(item): + assert int(len(list)) == int(info[-2]), "List does not have all records." + print("Records displayed correctly for " + item) + elif int(info[-2]) >= int(item): + assert int(len(list)) == int(item), "List does not have all records." + print("Records displayed correctly for " + item) + else: + print("No records to display") + + def verify_sorted_list(self, col_name): + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + self.wait_to_click((By.XPATH, self.user_sort.format(col_name))) + time.sleep(15) + if "User" in col_name: + list1 = self.find_elements(self.user_names_column_list) + elif "Completion" in col_name: + list1 = self.find_elements(self.completion_column_list) + elif "Submission" in col_name: + list1 = self.find_elements(self.submission_column_list) + elif "Form Name" in col_name: + list1 = self.find_elements(self.form_name_column_list) + elif "Difference" in col_name: + list1 = self.find_elements(self.difference_column_list_no_same) + else: + print("Invalid Column Name") + list1_names = list() + for item in list1: + list1_names.append(item.text) + if "Difference" in col_name: + sorted_list = natsorted(list1_names) + else: + sorted_list = sorted(list1_names) + print(list1_names) + print(sorted_list) + assert list1_names == sorted_list, "List is not sorted" + print("List is in ascending order") + self.wait_to_click((By.XPATH, self.user_sort.format(col_name))) + time.sleep(15) + if "User" in col_name: + list2 = self.find_elements(self.user_names_column_list) + elif "Completion" in col_name: + list2 = self.find_elements(self.completion_column_list) + elif "Submission" in col_name: + list2 = self.find_elements(self.submission_column_list) + elif "Form Name" in col_name: + list2 = self.find_elements(self.form_name_column_list) + elif "Difference" in col_name: + list2 = self.find_elements(self.difference_column_list_no_same) + else: + print("Invalid Column Name") + list2_names = list() + for item in list2: + list2_names.append(item.text) + if "Difference" in col_name: + rev_list = natsorted(list1_names, reverse=True) + else: + rev_list = sorted(list1_names, reverse=True) + print(list2_names) + print(rev_list) + assert list2_names == rev_list, "List is not sorted" + print("List is in descending order") + + def value_date_range_7_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return str(week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), week_ago.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_30_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + pastday = presentday - timedelta(30) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_last_month(self): + last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) + start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) + print(start_day_of_prev_month, last_day_of_prev_month) + return str(start_day_of_prev_month.strftime('%Y-%m-%d') + " to " + last_day_of_prev_month.strftime( + '%Y-%m-%d')), start_day_of_prev_month.strftime( + '%Y-%m-%d'), last_day_of_prev_month.strftime('%Y-%m-%d') + + def form_comp_sub_trends_search(self, date_range=UserData.date_range[0]): + date_string = start_date = end_date = '' + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Form Completion vs. Submission Trends page." + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(date_range))) + text = self.get_attribute(self.date_input, "value") + print(text) + if date_range == UserData.date_range[0]: + date_string, start_date, end_date = self.value_date_range_7_days() + elif date_range == UserData.date_range[1]: + date_string, start_date, end_date = self.value_date_range_last_month() + elif date_range == UserData.date_range[2]: + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + date_range) + + def date_validator(self, date_value, start_date, end_date): + dt = parse(date_value) + st = parse(start_date) + et = parse(end_date) + print(dt, st, et) + if st <= dt <= et: + assert True, "Date outside date range" + print("within range") + else: + print("not within range") + assert False + + def form_comp_sub_trends_search_custom_date(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Form Completion vs. Submission Trends page." + + date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 5) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string + Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present_and_displayed(self.date_range_error), "Date Range Error not displayed" + print("Date Range error correctly displayed") + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Form Completion vs. Submission Trends page." + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.select_date_from_picker(start_date, end_date) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[3]) + + def get_custom_dates_past(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + pastday = presentday - relativedelta(days=days, months=months, years=years) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def get_custom_dates_future(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + futureday = presentday + relativedelta(days=days, months=months, years=years) + return str(presentday.strftime('%Y-%m-%d') + " to " + futureday.strftime('%Y-%m-%d')), presentday.strftime( + '%Y-%m-%d'), futureday.strftime('%Y-%m-%d') + + def select_date_from_picker(self, start_date, end_date): + start_date = parse(start_date) + start_day = str(start_date.day) + start_month = str(start_date.month - 1) + start_year = str(start_date.year) + end_date = parse(end_date) + end_day = str(end_date.day) + end_month = str(end_date.month - 1) + end_year = str(end_date.year) + self.wait_for_element(self.from_month) + self.select_by_value(self.from_year, start_year) + time.sleep(2) + self.select_by_value(self.from_month, start_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.from_date.format(start_day))) + time.sleep(2) + self.wait_for_element(self.to_month) + self.select_by_value(self.to_year, end_year) + time.sleep(2) + self.select_by_value(self.to_month, end_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.to_date.format(end_day))) + time.sleep(2) + self.wait_to_click(self.apply_date) + + def form_comp_sub_trends_save_report(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_7_days() + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + time.sleep(10) + report_name = "Saved Form Completion Submission Trends Report " + fetch_random_string() + self.verify_favorite_empty(report_name) + report = self.save_report(report_name) + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + self.verify_favorite_created(report) + time.sleep(10) + self.verify_users_in_the_group() + self.delete_saved_report(report) + self.wait_to_click(self.form_comp_sub_trends_rep) + self.verify_favorite_empty(report_name) + + def verify_favorite_empty(self, report=None): + self.wait_to_click(self.favorite_button) + if report == None: + assert self.is_visible_and_displayed(self.empty_fav_list), "Favorites Already Present" + else: + assert not self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report)), + 30), "Favorite is already Present" + print("No Favorites yet.") + + def verify_favorite_created(self, report): + self.wait_to_click(self.favorite_button) + assert not self.is_visible_and_displayed(self.empty_fav_list, 10), "Favorites Already Present" + assert self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report))), "Favorite Not Present" + print("Favorites added.") + self.wait_to_click((By.XPATH, self.saved_fav.format(report))) + + def delete_saved_report(self, report): + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 120) + print("Report Present!") + self.click((By.XPATH, self.delete_saved.format(report))) + print("Deleted Saved Report") + time.sleep(5) + self.driver.refresh() + assert not self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 20) + print("Deleted Report Successfully") + + def save_report_error(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_7_days() + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + time.sleep(10) + report_name = "Saved Form Completion vs. Submission Trends Report Unsave" + fetch_random_string() + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.clear(self.name_field) + self.wait_to_click(self.save_report_button) + time.sleep(3) + assert self.is_present(self.report_save_error), "Error not displayed" + print("Error is correctly displayed") + self.js_click(self.cancel_report_button, 10) + time.sleep(5) + assert not self.is_visible_and_displayed(self.name_field, 10), "Save Report Form not closed" + print("Save Report Form is closed") + + def save_report(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.wait_for_element(self.save_report_button) + self.wait_to_clear_and_send_keys(self.name_field, report_name+Keys.TAB) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + time.sleep(2) + print("Cancel Button") + self.js_click(self.cancel_report_button) + time.sleep(5) + if self.is_present(self.save_report_button): + self.js_click(self.save_report_button) + print("Button is still present") + else: + print("report is canceled") + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.wait_for_element(self.save_report_button) + value = self.get_attribute(self.name_field, "value") + if value == report_name: + self.click(self.save_report_button) + print("save Button") + else: + self.wait_to_clear_and_send_keys(self.name_field, report_name+Keys.TAB) + self.js_click(self.save_report_button) + print("save Button") + assert not self.is_visible_and_displayed(self.save_report_button), "Save report name field is still present" + print("Save Report popup closed") + # self.driver.refresh() + time.sleep(5) + self.wait_for_element(self.saved_reports_menu_link) + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report_name)), 120) + print("Report Saved successfully!") + print("Report name: ", report_name) + return report_name + + def verify_case_type_data(self): + case_type_list = self.find_elements(self.case_created_column) + if len(case_type_list) > 0: + for item in case_type_list: + text = item.text + print("Cases created ", text) + if text == '0': + print("No Cases were created withing the given range") + else: + self.wait_to_click(item) + self.switch_to_next_tab() + time.sleep(10) + self.wait_for_element(self.case_list_table_title, 200) + self.scroll_to_bottom() + info = self.get_text(self.case_list_table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert info[-2] == text, "Case created count mismatch" + print("Cases created count matched") + self.select_by_value(self.case_list_page_dropdown, '100') + time.sleep(10) + cases = self.find_elements(self.case_list_table) + if len(cases) > 0: + for case in cases: + name = case.text + assert name == UserData.case_reassign, "Case Type mismatch" + print("Case Type matching") + time.sleep(2) + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def export_form_comp_sub_trends_to_excel(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(15) + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list_col = [] + for c in col: + list_col.append(c.text) + print(list_col) + self.wait_to_click(self.export_to_excel) + time.sleep(15) + print("Export to excel successful") + return list_col + + def compare_fct_with_email(self, web_data): + print(web_data) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + print(new_data.values) + ext_list = [] + ext_list.extend(new_data.values.tolist()) + list = [] + for i in range(len(ext_list) - 1)[:]: + list += ext_list[i] + print("List New: ", list) + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + if self.is_date(str(web_data[i])) == self.is_date(str(list[i])): + assert True, "Cpmparison failed for " + list[i] + " and " + web_data[i] + elif int(list[i]) == 0 and str(web_data[i]) != 'same': + print("Mismatch in values") + elif int(list[i]) <= 0 and str(web_data[i]) == 'same': + assert True, "Comparison failed for " + list[i] + " and " + web_data[i] + elif str(web_data[i]) == 'same' and int(list[i]) >= 0: + print("Mismatch in values") + else: + assert html.unescape(str(list[i])) == str(web_data[i]) or html.unescape(str(list[i])) in str(web_data[i]), "Comparison failed for " + list[i] + " and " + web_data[i] + + def export_form_comp_sub_trends_email(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Form Completion vs. Submission Trends page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list_col = [] + for c in col: + list_col.append(c.text) + print(list_col) + footer = self.find_elements(self.all_users_results_cells) + list_ft = [] + for f in footer: + list_ft.append(f.text) + print(list_ft) + list_col.extend(list_ft) + subject = UserData.email_form_comp_report + self.email_report_form_not_save(subject) + self.email_report_form(subject) + print("Export to excel successful") + + return list_col, subject + + def email_report_form_not_save(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.email_form_cancel_btn) + print("Email report form closed properly") + + def email_report_form(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.send_email_btn) + assert self.is_visible_and_displayed(self.email_success_message), "Email report not sent successfully" + print("Email report sent successfully") + + def compare_fct_with_html_table(self, table_data, web_data): + list = table_data + print("Table data rows: ", len(web_data), "Web data rows: ", len(list)) + print("Table List: ", web_data) + print("Web list: ", list) + assert len(web_data) == len(list), "Data in Both Email Body and Searched results do not match" + print("Both Email Body and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def form_comp_sub_trends_users_active(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_active_worker) + assert not self.is_present(self.remove_active_worker), "Active Mobile Worker is still not removed" + print("Active Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.app_login) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.app_login))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + list_user = self.find_elements((By.XPATH, self.result_rows_names.format(UserData.deactivated_user))) + for item in list_user: + text = item.text + print(text) + assert UserData.app_login in text, "Selected user " + UserData.app_login + " is not present in the results." + print("Selected user is present in the results") + + + def form_comp_sub_trends_users_deactivated(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_deactive_worker) + assert not self.is_present(self.remove_deactive_worker), "Deactivated Mobile Worker is still not removed" + print("Deactivated Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.mobile_testuser) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.deactivated_user))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert self.is_present((By.XPATH, self.result_rows_names.format( + UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is not present in the Deactivated worker list." + print("All Deactivated users are present") + + def verify_assigned_cases_count(self, actives, totals): + print("Sleeping for some time for the cases to be assigned") + time.sleep(60) + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + active_cases = self.find_elements(self.active_cases_column_list) + actives_new = [] + for items in active_cases: + actives_new.append(items.text) + total_cases = self.find_elements(self.total_cases_shared_column_list) + totals_new = [] + for items in total_cases: + totals_new.append(items.text) + print("Active Case: ", actives_new) + print("Total shared case: ", totals_new) + for i in range(len(actives_new)): + assert int(actives[i]) - 10 == actives_new[i], "Active Cases not reduced" + print("Active cases reduced") + for i in range(len(totals_new)): + assert int(totals[i]) - 10 == totals_new[i], "Active Cases not reduced" + print("Active cases reduced") + print("Cases successfully assigned") + + def filter_dates_and_verify(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string + Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in UserData.automation_group_users: + count = self.get_text((By.XPATH, self.total_form_counts.format(items))) + print(count) + time.sleep(1) + self.js_click((By.XPATH, self.result_rows_names.format(items))) + time.sleep(15) + self.wait_for_element(self.submit_history_table_title) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + assert UserData.reassign_cases_application == self.get_selected_text( + self.application_dropdown), "Application mismatched" + print("Application matched") + assert list(UserData.reasign_modules_forms.keys())[1] == self.get_selected_text( + self.module_dropdown), "Application mismatched" + print("Application matched") + assert UserData.reasign_modules_forms[list(UserData.reasign_modules_forms.keys())[1]][ + 0] == self.get_selected_text( + self.form_dropdown), "Application mismatched" + print("Application matched") + assert date_string == self.get_attribute(self.date_input, "value"), "Date Range mismatched" + print("Date Range matched") + assert self.is_present((By.XPATH, self.filter_column_name.format(filter))), "Incorrect column present" + print("Correct Column present") + self.scroll_to_bottom() + time.sleep(2) + # info = self.get_text(self.submit_history_table_info) + # print(info) + # info = str(info).split(" ") + # print("Total records: ", info[-2]) + # assert count == info[-2], "Form counts not matching" + # print("Form Count matching") + # if count == '0': + # assert self.is_present(self.empty_table) + # print("Correct value displayed") + time.sleep(5) + self.driver.back() + + def advanced_options(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[0]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[0]))) + time.sleep(1) + self.wait_to_click(self.show_adv_options) + assert self.is_selected(self.show_adv_options), "Show Advanced Options is not selected" + print("Show Advanced Option is successfully selected") + time.sleep(2) + assert self.is_present(self.known_forms), "Known Forms option not present" + assert self.is_present(self.unknown_forms), "Unknown Forms option not present" + assert self.is_present(self.application_type_dropdown), "Application Type dropdown not present" + active_apps, deleted_apps = self.known_forms_options() + self.unknown_forms_options(active_apps, deleted_apps) + self.wait_to_click(self.show_adv_options) + assert not self.is_selected(self.show_adv_options), "Show Advanced Options is still selected" + time.sleep(2) + assert not self.is_visible_and_displayed(self.known_forms, 10), "Known Forms option still present" + assert not self.is_visible_and_displayed(self.unknown_forms, 10), "Unknown Forms option still present" + print("All Show Advanced Options are working correctly") + + def known_forms_options(self): + if not self.is_selected(self.known_forms): + self.wait_to_click(self.known_forms) + assert self.is_selected(self.known_forms), "Known Forms radio button is not selected" + else: + assert self.is_selected(self.known_forms), "Known Forms radio button is not selected" + + self.verify_dropdown_options(self.application_type_dropdown, UserData.app_type_list) + self.select_by_text(self.application_type_dropdown, UserData.app_type_list[0]) + time.sleep(2) + assert not self.is_visible_and_displayed(self.application_dropdown, 10), "Application dropdown is still present" + print("Application dropdown successfully disappeared after selecting option ", UserData.app_type_list[0]) + self.select_by_text(self.application_type_dropdown, UserData.app_type_list[2]) + time.sleep(2) + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + list_app_active = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app_active[1:]: + assert "[Deleted Application]" in items, "Not a Deleted Application option" + print("All Deleted Application present") + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + list_value = self.find_elements(self.form_name_column_list) + if len(list_value)>0: + for items in list_value: + assert "Deleted" in items.text, "This is not a deleted form" + print("Deleted form name displayed") + time.sleep(2) + self.scroll_to_element(self.application_type_dropdown) + time.sleep(1) + self.select_by_text(self.application_type_dropdown, UserData.app_type_list[1]) + time.sleep(2) + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + list_app_deleted = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app_deleted[1:]: + assert "[Deleted Application]" not in items, "Deleted Application is present in the dropdown" + print("No Deleted Application present") + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + print("Correct Modules and Forms are present") + return list_app_active, list_app_deleted + + def unknown_forms_options(self, active, deleted): + if not self.is_selected(self.unknown_forms): + self.wait_to_click(self.unknown_forms) + assert self.is_selected(self.unknown_forms), "Unknown Forms radio button is not selected" + else: + assert self.is_selected(self.unknown_forms), "Unknown Forms radio button is not selected" + + assert self.is_visible_and_displayed(self.unknown_form_dropdown), "Unknown forms dropdown is not present" + print("Application dropdown successfully disappeared after selecting option ", UserData.app_type_list[0]) + list_app = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app[1:]: + assert items not in active or items not in deleted, "Not an Unknown Application option" + print("All Applications present are unknown") + + def generate_form_column_names(self, app, mod=None, forms=None): + column_list = [] + if mod == None and forms == None: + mod = list(UserData.reasign_modules_forms.keys()) + for m in mod: + for f in list(UserData.reasign_modules_forms[m]): + string = app+" > "+m+" > "+f + column_list.append(string) + elif mod !=None and forms == None: + for f in list(UserData.reasign_modules_forms[mod]): + string = app+" > "+mod+" > "+f + column_list.append(string) + else: + string = app + " > " + mod + " > " + forms + column_list.append(string) + print(column_list) + return column_list + + def form_column_verification(self, app, mod=None, form=None): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.application_dropdown, app) + if mod == None and form == None: + column_list = self.generate_form_column_names(app) + self.select_by_text(self.application_dropdown, app) + elif mod != None and form == None: + column_list = self.generate_form_column_names(app, mod) + self.select_by_text(self.application_dropdown, app) + self.select_by_text(self.module_dropdown, mod) + else: + column_list = self.generate_form_column_names(app, mod, form) + self.select_by_text(self.application_dropdown, app) + self.select_by_text(self.module_dropdown, mod) + self.select_by_text(self.form_dropdown, form) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + if self.is_present(self.empty_table): + print("No data for the selected filter") + else: + self.verify_users_in_the_group() + list_value = self.find_elements(self.form_name_column_list) + for items in list_value: + name = items.text + assert name in column_list, "Form name not valid" + print("Valid form name") + # for items in column_list: + # assert self.is_present((By.XPATH, self.column_names.format(items))), "Form Name Column not present: " + items + self.js_click(self.user_names_column_first) + time.sleep(15) + self.wait_for_element(self.submit_history_table_title) + print("Successfully redirected to Submit History Page") + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + if mod == None and form == None: + assert UserData.reassign_cases_application == self.get_selected_text( + self.application_dropdown), "Application mismatched" + print("Application matched") + elif mod != None and form == None: + assert UserData.reassign_cases_application == self.get_selected_text( + self.application_dropdown), "Application mismatched" + print("Application matched") + assert list(UserData.reasign_modules_forms.keys())[1] == self.get_selected_text(self.module_dropdown), "Application mismatched" + print("Application matched") + else: + assert UserData.reassign_cases_application == self.get_selected_text( + self.application_dropdown), "Application mismatched" + print("Application matched") + assert list(UserData.reasign_modules_forms.keys())[1] == self.get_selected_text( + self.module_dropdown), "Application mismatched" + print("Application matched") + assert UserData.reasign_modules_forms[list(UserData.reasign_modules_forms.keys())[1]][0] == self.get_selected_text(self.form_dropdown), "Application mismatched" + print("Application matched") + assert text == self.get_attribute(self.date_input, "value"), "Date Range mismatched" + print("Date Range matched") + self.scroll_to_bottom() + time.sleep(2) + + def no_form_selected(self): + self.wait_to_click(self.form_comp_sub_trends_rep) + self.wait_for_element(self.apply_id) + assert self.form_comp_sub_trends_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + assert self.is_visible_and_displayed(self.no_form_selected_msg), "No form selected message is not displayed." + print("No form selected message is displayed correctly") \ No newline at end of file diff --git a/ElasticSearchTests/testPages/project_performance/__init__.py b/ElasticSearchTests/testPages/project_performance/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/project_performance/project_performance_page.py b/ElasticSearchTests/testPages/project_performance/project_performance_page.py new file mode 100644 index 000000000..12a1ad847 --- /dev/null +++ b/ElasticSearchTests/testPages/project_performance/project_performance_page.py @@ -0,0 +1,911 @@ +import html +import os +import time + +import dateutil.relativedelta +import pandas as pd + +from datetime import datetime, timedelta, date +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from selenium.webdriver import ActionChains + +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from ElasticSearchTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec + +""""Contains test page elements and functions related to the Reports module""" + + +class ProjectPerformancePage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.proj_perf_rep = (By.LINK_TEXT, "Project Performance") + self.proj_perf_TITLE = "Project Performance - CommCare HQ" + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + + self.low_perf_results = (By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody/tr)[1]") + self.low_perf_results_cells = (By.XPATH, "(//table[contains(@id,'DataTables_Table')])[1]/tbody/tr/td") + self.low_perf_user_edit = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody/tr/td[1]/a/div//a[.='Edit User Information'])[1]") + self.low_perf_user_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Username'])[1]") + self.low_perf_forms_submitted_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Change in Forms Submitted'])[1]") + self.low_perf_last_month_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Last Month'])[1]") + self.low_perf_this_month_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='This Month'])[1]") + self.low_perf_arrow_values = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='This Month'])[1]") + + self.inactive_results = (By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody/tr)[2]") + self.inactive_results_cells = (By.XPATH, "(//table[contains(@id,'DataTables_Table')])[2]/tbody/tr/td") + self.inactive_user_edit = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody/tr/td[1]/a/div//a[.='Edit User Information'])[2]") + self.inactive_user_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Username'])[2]") + self.inactive_forms_submitted_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Change in Forms Submitted'])[2]") + self.inactive_last_month_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Last Month'])[2]") + self.inactive_this_month_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='This Month'])[2]") + + self.high_perf_results = (By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody/tr)[3]") + self.high_perf_results_cells = (By.XPATH, "(//table[contains(@id,'DataTables_Table')])[3]/tbody/tr/td") + self.high_perf_user_edit = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody/tr/td[1]/a/div//a[.='Edit User Information'])[3]") + self.high_perf_user_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Username'])[3]") + self.high_perf_forms_submitted_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Change in Forms Submitted'])[3]") + self.high_perf_last_month_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='Last Month'])[3]") + self.high_perf_this_month_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/thead//th[.='This Month'])[3]") + + self.down_arrows = (By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody//td/span[@class='fa fa-chevron-down'])") + self.up_arrows = ( + By.XPATH, "//table[contains(@id,'DataTables_Table')]/tbody//td/span[@class='fa fa-chevron-up']") + + self.up_arrows_iterables = "(//table[contains(@id,'DataTables_Table')]/tbody//td/span[@class='fa fa-chevron-up'])[{}]" + self.down_arrows_iterables = "(//table[contains(@id,'DataTables_Table')]/tbody//td/span[@class='fa fa-chevron-down'])[{}]" + + self.group_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.custome_remove_btn = "//li/span[contains(.,'{}')]//preceding-sibling::button[@class='select2-selection__choice__remove']" + self.user_from_list = "//li[contains(.,'{}')]" + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + self.user_column = ( + By.XPATH, "(//table[contains(@id,'DataTables_Table')]/tbody/tr/td[1]/a/div//a[.='Edit User Information']") + self.active_cases_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_case_activity']/div[contains(.,'# Active Cases')])[1]") + self.inactive_cases_column = ( + By.XPATH, + "(//thead/tr/th[@aria-controls='report_table_case_activity']/div[contains(.,'# Inactive Cases')])[1]") + + self.users_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.users_list = (By.XPATH, "//ul[contains(@class,'select2-results__options')]/li") + self.users_list_empty = ( + By.XPATH, "//ul[contains(@id,'select2-emw-bi-results')]/li[.='The results could not be loaded.']") + + self.column_names = "(//thead/tr/th[@aria-controls='report_table_case_activity']/div[@data-title='{}'])[{}]" + self.column_group_names = "(//thead/tr/th//strong[.='{}'])[1]" + self.user_names_column_list = "(//table[contains(@id,'DataTables_Table')]//tbody//td[1])[{}]" + self.last_submission_column_list = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[4]") + self.result_table = (By.XPATH, "(//div[@id='report-content']//table//tbody//td[1])[1]") + self.results_rows = (By.XPATH, "//tbody//td[not(contains(.,'No data'))]//parent::tr") + self.result_rows_names = "//tbody/tr/td[1][contains(.,'{}')]" + self.all_users_row_names = (By.XPATH, "//tfoot/td[contains(.,'All Users')]") + self.hide_filters_options = (By.XPATH, "//a[.='Hide Filter Options']") + self.show_filters_options = (By.XPATH, "//a[.='Show Filter Options']") + self.user_sort = ( + By.XPATH, "(//text()[contains(.,'User')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]") + self.active_cases_column_list = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[7]") + self.total_cases_shared_column_list = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[8]") + self.column_name_headers = "//table[@id='report_table_case_activity']//thead//th/div/div[contains(.,'{}')]" + + + # Pagination + self.page_list_dropdown = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//select" + self.table_info = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//div[@class='dataTables_info']" + self.prev_page_button = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//ul[@class='pagination']/li[@class='prev']/a" + self.next_page_button = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//ul[@class='pagination']/li[@class='next']/a" + self.prev_page_button_disabled = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//ul[@class='pagination']/li[@class='prev disabled']/a" + self.next_page_button_disabled = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//ul[@class='pagination']/li[@class='next disabled']/a" + self.page_button = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//ul[@class='pagination']/li/a[.='{}']" + self.pagination_list = "(//table[contains(@id,'DataTables_Table')])[{}]//following-sibling::div//ul[@class='pagination']/li/a" + + # Custom date selector + self.from_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='monthselect']") + self.from_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='yearselect']") + self.from_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + + self.to_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='monthselect']") + self.to_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='yearselect']") + self.to_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + self.apply_date = ( + By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Apply']") + self.remove_active_worker = (By.XPATH, + "//span[.='[Active Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_deactive_worker = (By.XPATH, + "//span[.='[Deactivated Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + + # Save Report and Favorites + self.favorite_button = (By.XPATH, "//button[contains(.,'Favorites')]") + self.empty_fav_list = (By.XPATH, '//a[.="You don\'t have any favorites"]') + self.saved_fav = "//a[contains(.,'{}')][contains(@data-bind,'text: name')]" + self.save_config_button = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.name_field = (By.XPATH, "//input[@data-bind='value: name']") + self.description_field = (By.XPATH, "//textarea[@data-bind='value: description']") + self.date_range_field_select = (By.XPATH, "//select[@data-bind='value: date_range']") + self.save_report_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Save']") + self.try_again_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Try Again']") + self.report_save_error = (By.XPATH, "//div[.='Some required fields are missing. Please complete them before saving.']") + self.cancel_report_button = (By.XPATH, "//div/a[.='Cancel']") + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = "//a[text()='{}']" + self.delete_saved = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + + # Case Type Verify + self.case_created_column = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[5]//a") + self.case_created_title = (By.XPATH, "//table[@id='report_table_case_activity']//tbody//td[5]//span") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr/td[1]") + self.case_list_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Case List')]") + self.case_list_table_info = (By.XPATH, "//div[@id='report_table_case_list_info']") + self.case_list_page_dropdown = (By.XPATH, "//select[@name='report_table_case_list_length']") + self.owner_column_list = (By.XPATH, "//tbody//td[3]") + self.empty_table = (By.XPATH, "//tr/td[contains(.,'No data available to display.')]") + + # Email report + self.email_report_btn = (By.XPATH, "//a[@id='email-report']") + self.email_subject_field = (By.XPATH, "//input[@id='id_subject']") + self.email_form_cancel_btn = (By.XPATH, "//input[@id='button-id-close']") + self.send_email_btn = (By.XPATH, "//input[@id='submit-id-submit_btn']") + self.email_success_message = (By.XPATH, "//*[.='Report successfully emailed']") + self.additional_recipients = (By.XPATH, "//textarea[contains(@aria-describedby,'id_recipient_emails')]") + self.reports_notes_field = (By.XPATH, "//textarea[@data-bind='value: notes']") + + + + def hide_filters(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.hide_filters_options) + self.click(self.hide_filters_options) + time.sleep(2) + assert not self.is_visible_and_displayed(self.group_field, 10), "Group or Locations field is still present" + assert not self.is_visible_and_displayed(self.apply_id, 10), "Apply button is still present" + assert not self.is_visible_and_displayed(self.favorite_button, 10), "Favorites button is still present" + assert not self.is_visible_and_displayed(self.save_config_button, 10), "Save button is still present" + assert self.is_present(self.show_filters_options), "Show Filters Options is not present" + print("All filters are hidden!") + + def show_filters(self): + self.wait_for_element(self.show_filters_options) + self.click(self.show_filters_options) + time.sleep(2) + assert self.is_visible_and_displayed(self.group_field), "Group or Locations field is not present" + assert self.is_visible_and_displayed(self.apply_id), "Apply button is not present" + assert self.is_visible_and_displayed(self.favorite_button), "Favorites button is not present" + assert self.is_visible_and_displayed(self.save_config_button), "Save button is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_proj_perf_page_fields(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + assert self.proj_perf_TITLE in self.driver.title, "This is not the Project Performance page." + assert self.is_visible_and_displayed(self.group_field), "Group or Locations field is not present" + assert self.is_visible_and_displayed(self.apply_id), "Apply button is not present" + assert self.is_visible_and_displayed(self.favorite_button), "Favorites button is not present" + assert self.is_visible_and_displayed(self.save_config_button), "Save button is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_tables_columns(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + assert self.proj_perf_TITLE in self.driver.title, "This is not the Project Performance page." + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.low_perf_user_column), "User Column not present for Low Performance Table" + assert self.is_present(self.low_perf_last_month_column), "Last Month Column not present for Low Performance Table" + assert self.is_present(self.low_perf_this_month_column), "This Month Column not present for Low Performance Table" + + assert self.is_present(self.inactive_user_column), "User Column not present for Inactive Table" + assert self.is_present( + self.inactive_last_month_column), "Last Month Column not present for Inactive Table" + assert self.is_present( + self.inactive_this_month_column), "This Month Column not present for Inactive Table" + + assert self.is_present(self.high_perf_user_column), "User Column not present for High Performance Table" + assert self.is_present( + self.high_perf_last_month_column), "Last Month Column not present for High Performance Table" + assert self.is_present( + self.high_perf_this_month_column), "This Month Column not present for High Performance Table" + down_arrow_lists = self.find_elements(self.down_arrows) + print(len(down_arrow_lists)) + if len(down_arrow_lists)>0: + for i in range(len(down_arrow_lists)): + style = self.get_attribute((By.XPATH,self.down_arrows_iterables.format(i+1)), "style") + print(style) + assert UserData.arrows_code[0] in style or UserData.arrows_code[1] in style, "Arrow is not Red for Down arrow" + print("Arrow is Red for Down arrow") + + up_arrow_lists = self.find_elements(self.up_arrows) + len(up_arrow_lists) + if len(up_arrow_lists) > 0: + for i in range(len(up_arrow_lists)): + style = self.get_attribute((By.XPATH,self.up_arrows_iterables.format(i+1)), "style") + print(style) + assert UserData.arrows_code[2] in style or UserData.arrows_code[3] in style, "Arrow is not Green for Up arrow" + print("Arrow is Green for Up arrow") + + + def verify_user_lookup_table(self): + self.wait_to_click(self.group_field) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_list_empty, 10), "Case Type List is not empty" + list = self.find_elements(self.users_list) + print(len(list)) + assert int(len(list)) >= 1 + print("A Look up for Case type is successfully loaded") + + def date_generator(self, start, end): + start_date = parse(start) + end_date = parse(end) # perhaps date.now() + date_list = [] + delta = end_date - start_date # returns timedelta + + for i in range(delta.days + 1): + day = start_date + timedelta(days=i) + day = str(day.strftime('%Y-%m-%d')) + date_list.append(day) + print(day) + return date_list + + + def verify_users_in_the_group(self, cond="yes"): + list = self.find_elements(self.results_rows) + if len(list) > 0: + if cond == "yes": + for item in UserData.automation_group_users: + if self.is_present((By.XPATH, self.result_rows_names.format( + item))) == False: + print("No results for user: ", item) + else: + assert self.is_present((By.XPATH, self.result_rows_names.format( + item))), "Group user " + item + " is not present in results." + print("Group User " + item + " is present in results.") + elif cond == "no": + for item in UserData.automation_group_users: + assert not self.is_present((By.XPATH, self.result_rows_names.format( + item))), "Group user " + item + " is present in results." + print("Group User " + item + " is not present in results.") + + def proj_perf_pagination_list(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + assert self.proj_perf_TITLE in self.driver.title, "This is not the Project Performance page." + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + # For Low Performance table + for i in range(0,3): + pages = self.find_elements((By.XPATH,self.pagination_list.format(i+1))) + pages_count = len(pages) - 2 + print("Total Pages: ", pages_count) + first_page = pages[1].text + last_page = pages[-2].text + if pages_count > 1: + assert self.is_present((By.XPATH, self.prev_page_button_disabled.format(i+1))), "Previous button is not disabled." + print("Previous button disabled correctly") + print("Clicking on page " + last_page) + self.wait_to_click((By.XPATH, self.page_button.format(i+1, last_page))) + time.sleep(15) + assert self.is_present((By.XPATH, self.next_page_button_disabled.format(i+1))), "Next button is not disabled." + print("Next button disabled correctly") + time.sleep(5) + print("Clicking on page " + first_page) + self.wait_to_click((By.XPATH, self.page_button.format(i+1,first_page))) + time.sleep(15) + list1 = self.find_elements((By.XPATH, self.user_names_column_list.format(i+1))) + list1_names = list() + for item in list1: + list1_names.append(item.text) + self.wait_to_click(self.next_page_button) + time.sleep(10) + list2 = self.find_elements((By.XPATH, self.user_names_column_list.format(i+1))) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print(list1_names, list2_names) + assert list1_names != list2_names, "Both Pages have same values" + print("Next button functioning correctly.") + self.wait_to_click(self.prev_page_button) + time.sleep(5) + list3 = self.find_elements((By.XPATH, self.user_names_column_list.format(i+1))) + list3_names = list() + for item in list3: + list3_names.append(item.text) + print(list1_names, list2_names, list3_names) + assert list1_names == list3_names and list2_names != list3_names, "Page contains same data as the previous" + print("Prev button functioning correctly.") + else: + print("Not enough users are present.") + assert self.is_present((By.XPATH, self.prev_page_button_disabled.format(i+1))) + assert self.is_present((By.XPATH, self.next_page_button_disabled.format(i+1))) + print("Both Previous and Next Page buttons are disabled correctly.") + + def verify_pagination_dropdown(self): + for i in range(0, 3): + info = self.get_text((By.XPATH, self.table_info.format(i+1))) + info = str(info).split(" ") + print("Total records: ", info[-2]) + if int(info[-2]) > 10: + for item in UserData.pagination: + self.select_by_value((By.XPATH,self.page_list_dropdown.format(i+1)), item) + time.sleep(10) + list = self.find_elements((By.XPATH, self.user_names_column_list.format(i+1))) + print(len(list)) + if int(info[-2]) < int(item): + assert int(len(list)) == int(info[-2]), "List does not have all records." + print("Records displayed correctly for " + item) + elif int(info[-2]) >= int(item): + assert int(len(list)) == int(item), "List does not have all records." + print("Records displayed correctly for " + item) + else: + print("No records to display") + else: + print("Not enough Record to be displayed with Pagination List") + + + def value_date_range_7_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return str(week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), week_ago.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_30_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + pastday = presentday - timedelta(30) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_last_month(self): + last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) + start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) + print(start_day_of_prev_month, last_day_of_prev_month) + return str(start_day_of_prev_month.strftime('%Y-%m-%d') + " to " + last_day_of_prev_month.strftime( + '%Y-%m-%d')), start_day_of_prev_month.strftime( + '%Y-%m-%d'), last_day_of_prev_month.strftime('%Y-%m-%d') + + def case_activity_search(self, date_range=UserData.date_range[0]): + date_string = start_date = end_date = '' + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not theProject Performance page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(date_range))) + text = self.get_attribute(self.date_input, "value") + print(text) + if date_range == UserData.date_range[0]: + date_string, start_date, end_date = self.value_date_range_7_days() + elif date_range == UserData.date_range[1]: + date_string, start_date, end_date = self.value_date_range_last_month() + elif date_range == UserData.date_range[2]: + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + date_range) + + def date_validator(self, date_value, start_date, end_date): + dt = parse(date_value) + st = parse(start_date) + et = parse(end_date) + print(dt, st, et) + if st <= dt <= et: + assert True, "Date outside date range" + print("within range") + else: + print("not within range") + assert False + + def case_activity_search_custom_date(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not theProject Performance page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 5) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string+Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present_and_displayed(self.date_range_error), "Date Range Error not displayed" + print("Date Range error correctly displayed") + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not theProject Performance page." + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.select_date_from_picker(start_date, end_date) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[3]) + + + def get_custom_dates_past(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + pastday = presentday - relativedelta(days=days, months=months, years=years) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def get_custom_dates_future(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + futureday = presentday + relativedelta(days=days, months=months, years=years) + return str(presentday.strftime('%Y-%m-%d') + " to " + futureday.strftime('%Y-%m-%d')), presentday.strftime( + '%Y-%m-%d'), futureday.strftime('%Y-%m-%d') + + def select_date_from_picker(self, start_date, end_date): + start_date = parse(start_date) + start_day = str(start_date.day) + start_month = str(start_date.month - 1) + start_year = str(start_date.year) + end_date = parse(end_date) + end_day = str(end_date.day) + end_month = str(end_date.month - 1) + end_year = str(end_date.year) + self.wait_for_element(self.from_month) + self.select_by_value(self.from_year, start_year) + time.sleep(2) + self.select_by_value(self.from_month, start_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.from_date.format(start_day))) + time.sleep(2) + self.wait_for_element(self.to_month) + self.select_by_value(self.to_year, end_year) + time.sleep(2) + self.select_by_value(self.to_month, end_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.to_date.format(end_day))) + time.sleep(2) + self.wait_to_click(self.apply_date) + + def proj_perf_save_report(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + assert self.proj_perf_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.group_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + time.sleep(10) + report_name = "Saved Project Performance Report " + fetch_random_string() + self.verify_favorite_empty(report_name) + self.save_report_donot_save(report_name) + self.save_report(report_name) + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + self.verify_favorite_created(report_name) + time.sleep(10) + self.verify_users_in_the_group() + self.delete_saved_report(report_name) + self.wait_to_click(self.proj_perf_rep) + self.verify_favorite_empty(report_name) + + def verify_favorite_empty(self, report=None): + self.wait_to_click(self.favorite_button) + if report==None: + assert self.is_visible_and_displayed(self.empty_fav_list), "Favorites Already Present" + else: + assert not self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report)),30), "Favorite is already Present" + print("No Favorites yet.") + + def verify_favorite_created(self, report): + self.wait_to_click(self.favorite_button) + assert not self.is_visible_and_displayed(self.empty_fav_list, 10), "Favorites Already Present" + assert self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report))), "Favorite Not Present" + print("Favorites added.") + self.wait_to_click((By.XPATH, self.saved_fav.format(report))) + + def delete_saved_report(self, report): + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 120) + print("Report Present!") + self.click((By.XPATH, self.delete_saved.format(report))) + print("Deleted Saved Report") + time.sleep(5) + self.driver.refresh() + assert not self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 20) + print("Deleted Report Successfully") + + def save_report_donot_save(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + time.sleep(5) + assert self.is_present(self.name_field), "Name Field is not present" + assert self.is_present(self.description_field), "Description field is not present" + assert self.is_present(self.cancel_report_button), "Cancel button is not present" + assert self.is_present(self.save_report_button), "Save button is not present" + self.wait_to_clear_and_send_keys(self.name_field, report_name) + self.wait_to_click(self.cancel_report_button) + time.sleep(2) + assert not self.is_visible_and_displayed(self.name_field, 10), "Save Report Form not closed" + print("Save Report Form is closed") + + def save_report(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + assert self.is_present(self.name_field), "Name Field is not present" + assert self.is_present(self.description_field), "Description field is not present" + assert self.is_present(self.cancel_report_button), "Cancel button is not present" + assert self.is_present(self.save_report_button), "Save button is not present" + self.clear(self.name_field) + self.wait_to_click(self.save_report_button) + time.sleep(3) + assert self.is_present(self.report_save_error), "Error not displayed" + print("Error is correctly displayed") + self.wait_to_clear_and_send_keys(self.name_field, report_name) + self.wait_to_click(self.try_again_button) + time.sleep(2) + self.driver.refresh() + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report_name)), 120) + print("Report Saved successfully!") + print("Report name: ", report_name) + return report_name + + def verify_case_type_data(self): + case_type_list = self.find_elements(self.case_created_column) + if len(case_type_list) > 0: + for item in case_type_list: + text = item.text + print("Cases created ", text) + if text == '0': + print("No Cases were created withing the given range") + else: + self.wait_to_click(item) + self.switch_to_next_tab() + time.sleep(10) + self.wait_for_element(self.case_list_table_title, 200) + self.scroll_to_bottom() + info = self.get_text(self.case_list_table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert info[-2] == text, "Case created count mismatch" + print("Cases created count matched") + self.select_by_value(self.case_list_page_dropdown, '100') + time.sleep(10) + cases = self.find_elements(self.case_list_table) + if len(cases) > 0: + for case in cases: + name = case.text + assert name == UserData.case_reassign, "Case Type mismatch" + print("Case Type matching") + time.sleep(2) + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def export_proj_perf_to_excel(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + assert self.proj_perf_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.group_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + self.wait_for_element(self.low_perf_results) + col_low = self.find_elements(self.low_perf_results_cells) + list_low = [] + for c in col_low: + list_low.append(c.text) + print(list_low) + col_inactive = self.find_elements(self.inactive_results_cells) + list_inactive = [] + for c in col_inactive: + list_inactive.append(c.text) + print(list_inactive) + col_high = self.find_elements(self.high_perf_results_cells) + list_high = [] + for c in col_high: + list_high.append(c.text) + print(list_high) + self.wait_to_click(self.export_to_excel) + time.sleep(5) + print("Export to excel successful") + return list_low, list_inactive, list_high + + def compare_pp_with_excel(self, low, inactive, high): + low = list(map(lambda x: x.replace(' ', '--'), low)) + inactive = list(map(lambda x: x.replace(' ', '--'), inactive)) + high = list(map(lambda x: x.replace(' ', '--'), high)) + web_data = [inactive, low, high] + print("Low Performance: ",low) + print("Inactive: ", inactive) + print("High Performance: ", high) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + df_sheet_all = pd.read_excel(path, sheet_name=None, index_col=None) + for i in range(len(UserData.proj_perf_excel_tabs))[1:]: + data = df_sheet_all[UserData.proj_perf_excel_tabs[i]] + print(UserData.proj_perf_excel_tabs[i], data) + data['last_month'] = data['delta_last_month'].astype(str) +"--"+ data['last_month_forms'].astype(str) + data['this_month'] = data['delta_this_month'].astype(str) +"--"+ data['this_month_forms'].astype(str) + data = (data.loc[:, ~data.columns.isin(['user_id', 'last_month_forms','delta_last_month','this_month_forms','delta_this_month','is_performing'])]) + # Create an empty list + row_list = [] + # Iterate over each row + for index, rows in data.iterrows(): + # Create list for the current row + my_list = [rows.username, rows.last_month, rows.this_month] + # append the list to the final list + row_list.extend(my_list) + # Print the list + print("Final list: ",row_list) + if "No data available in table" in web_data[i-1]: + assert len(row_list) == 0, "Data mismatch" + print("Data is matching") + else: + assert row_list[0] == web_data[i-1] or row_list == web_data[i-1], "Data mismatch" + print("Data is matching") + + + def export_proj_perf_email(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + assert self.proj_perf_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.group_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + self.wait_for_element(self.low_perf_results) + col_low = self.find_elements(self.low_perf_results_cells) + list_low = [] + for c in col_low: + list_low.append(c.text) + print(list_low) + col_inactive = self.find_elements(self.inactive_results_cells) + list_inactive = [] + for c in col_inactive: + list_inactive.append(c.text) + print(list_inactive) + col_high = self.find_elements(self.high_perf_results_cells) + list_high = [] + for c in col_high: + list_high.append(c.text) + print(list_high) + subject = UserData.email_proj_perf_report + self.email_report_form(subject) + print("Export to excel successful") + list_low = list(map(lambda x: x.replace(' ', '--'), list_low)) + list_inactive = list(map(lambda x: x.replace(' ', '--'), list_inactive)) + list_high = list(map(lambda x: x.replace(' ', '--'), list_high)) + web_data=[list_low+ list_inactive+ list_high] + print("Sleeping for some time for the email to be sent") + time.sleep(30) + return web_data, subject + + def email_report_form_not_save(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + assert self.is_present(self.additional_recipients), "Additional recipients field is not present" + print("Additional recipients field is present") + assert self.is_present(self.reports_notes_field), "Report notes field is not present" + print("Report notes field is present") + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.email_form_cancel_btn) + print("Email report form closed properly") + + def email_report_form(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + assert self.is_present(self.additional_recipients), "Additional recipients field is not present" + print("Additional recipients field is present") + assert self.is_present(self.reports_notes_field), "Report notes field is not present" + print("Report notes field is present") + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.send_email_btn) + assert self.is_visible_and_displayed(self.email_success_message), "Email report not sent successfully" + print("Email report sent successfully") + + def compare_proj_perf_with_html_table(self, table_data, web_data): + print("table data: ",table_data) + print("Web data: ", web_data) + assert len(web_data) == len(table_data), "Data in Both Email Body and Searched results do not match" + print("Both Email Body and Searched results have same amount of data") + for i in range(len(table_data)): + print("Comparing ", html.unescape(str(table_data[i])), " with ", str(web_data[i])) + assert html.unescape(str(table_data[i])) == str(web_data[i]), "Cpmparision failed for " + table_data[i] + " and " + \ + web_data[i] + + def proj_perf_group_selection(self): + self.wait_to_click(self.proj_perf_rep) + self.wait_for_element(self.apply_id) + assert self.proj_perf_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.group_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(2) + self.wait_to_click(self.apply_id) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + self.wait_to_click((By.XPATH, self.custome_remove_btn.format(UserData.user_group))) + time.sleep(2) + assert not self.is_present((By.XPATH, self.custome_remove_btn.format(UserData.user_group))), "Group still present" + print("Group removed successfully") + self.send_keys(self.group_field, UserData.location) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.location))) + time.sleep(2) + self.wait_to_click(self.apply_id) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group("no") + self.wait_to_click((By.XPATH, self.custome_remove_btn.format(UserData.location))) + time.sleep(2) + assert not self.is_present( + (By.XPATH, self.custome_remove_btn.format(UserData.location))), "Location still present" + print("Location removed successfully") + self.send_keys(self.group_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(2) + self.send_keys(self.group_field, UserData.location) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.location))) + self.wait_to_click(self.apply_id) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + assert self.is_present((By.XPATH, self.custome_remove_btn.format(UserData.user_group))), "Group not present" + assert self.is_present((By.XPATH, self.custome_remove_btn.format(UserData.location))), "Location not present" + print("Multiple options selected successfully") + + + def case_activity_users_deactivated(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_deactive_worker) + assert not self.is_present(self.remove_deactive_worker), "Deactivated Mobile Worker is still not removed" + print("Deactivated Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[1]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[1]))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert self.is_present((By.XPATH, self.result_rows_names.format(UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is not present in the Deactivated worker list." + print("All Deactivated users are present") + + def user_data_verify(self): + self.wait_to_click(self.case_activity_rep) + self.wait_for_element(self.apply_id) + assert self.case_activity_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.case_type_dropdown, UserData.case_reassign) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in UserData.automation_group_users: + self.wait_to_click((By.PARTIAL_LINK_TEXT, items)) + time.sleep(15) + self.wait_for_element(self.case_list_table_title) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + time.sleep(2) + owner_list = self.find_elements(self.owner_column_list) + print(len(owner_list)) + if len(owner_list)>1: + for owner in owner_list: + text = owner.text + assert items in text or text in UserData.user_group, "Owner does not match" + print("Owner matching") + time.sleep(5) + self.driver.back() + time.sleep(2) + self.driver.back() + + + diff --git a/ElasticSearchTests/testPages/reports/__init__.py b/ElasticSearchTests/testPages/reports/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/reports/report_page.py b/ElasticSearchTests/testPages/reports/report_page.py new file mode 100644 index 000000000..6e5523e49 --- /dev/null +++ b/ElasticSearchTests/testPages/reports/report_page.py @@ -0,0 +1,802 @@ +import os +import time +import html +from datetime import datetime, timedelta +import re +import pandas as pd +from selenium.webdriver import ActionChains + +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from HQSmokeTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec + +""""Contains test page elements and functions related to the Reports module""" + + +class ReportPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + self.report_name_form = "report form " + fetch_random_string() + self.report_name_case = "report case " + fetch_random_string() + self.report_name_saved = "saved form " + fetch_random_string() + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.worker_activity_rep = (By.LINK_TEXT, "Worker Activity") + self.daily_form_activity_rep = (By.LINK_TEXT, "Daily Form Activity") + self.submissions_by_form_rep = (By.LINK_TEXT, "Submissions By Form") + self.form_completion_rep = (By.LINK_TEXT, "Form Completion Time") + self.case_activity_rep = (By.LINK_TEXT, "Case Activity") + self.completion_vs_submission_rep = (By.LINK_TEXT, "Form Completion vs. Submission Trends") + self.worker_activity_times_rep = (By.LINK_TEXT, "Worker Activity Times") + self.project_performance_rep = (By.LINK_TEXT, "Project Performance") + + # Inspect Data Reports + self.submit_history_rep = (By.LINK_TEXT, "Submit History") + self.case_list_rep = (By.LINK_TEXT, "Case List") + self.case_list_explorer = (By.LINK_TEXT, "Case List Explorer") + + # Manage Deployments Reports + self.application_status_rep = (By.LINK_TEXT, "Application Status") + self.agg_user_status_rep = (By.LINK_TEXT, "Aggregate User Status") + self.raw_forms_rep = (By.LINK_TEXT, "Raw Forms, Errors & Duplicates") + self.device_log_rep = (By.LINK_TEXT, "Device Log Details") + self.app_error_rep = (By.LINK_TEXT, "Application Error Report") + + # Messaging Reports + self.sms_usage_rep = (By.LINK_TEXT, "SMS Usage") + self.messaging_history_rep = (By.LINK_TEXT, "Messaging History") + self.message_log_rep = (By.LINK_TEXT, "Message Log") + self.sms_opt_out_rep = (By.LINK_TEXT, "SMS Opt Out Report") + self.scheduled_messaging_rep = (By.LINK_TEXT, "Scheduled Messaging Events") + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + self.save_xpath = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.custom_report_content_id = (By.ID, "report_table_configurable_wrapper") + self.edit_report_id = (By.ID, "edit-report-link") + self.delete_report_xpath = (By.XPATH, "//input[contains(@value,'Delete')]") + self.homepage = (By.XPATH, ".//a[@href='/homepage/']") + + # Report Builder + self.create_new_rep_id = (By.ID, "create-new-report-left-nav") + self.report_name_textbox_id = (By.ID, "id_report_name") + + self.next_button_id = (By.ID, "js-next-data-source") + self.save_and_view_button_id = (By.ID, "btnSaveView") + self.form_or_cases = (By.XPATH, "//select[@data-bind='value: sourceType']") + self.select_form_type = (By.XPATH, "//option[@value='form']") + self.select_app = (By.XPATH, "//option[text()='Village Health']") + self.application = (By.XPATH, "//select[@data-bind='value: application']") + + self.select_source_id = (By.XPATH, "//select[@id='id_source']") + self.select_form_type_value = "form" + self.select_source_id_form_value = "Case List / Registration Form" + self.select_source_id_case_value = "commcare-user" + + # Saved Reports + self.new_saved_report_name = (By.ID, "name") + self.save_confirm = (By.XPATH, '//div[@class = "btn btn-primary"]') + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = (By.XPATH, "//a[text()='" + self.report_name_saved + "']") + self.delete_saved = (By.XPATH, + "(//a[text()='" + self.report_name_saved + "']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]") + self.delete_saved_report_link = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + self.all_saved_reports = ( + By.XPATH, "//td[a[contains(.,'saved form')]]//following-sibling::td/button[contains(@data-bind,'delete')]") + + # Scheduled Reports + self.scheduled_reports_menu_xpath = (By.XPATH, "//a[@href='#scheduled-reports']") + self.create_scheduled_report = (By.XPATH, "//a[@class='btn btn-primary track-usage-link']") + self.available_reports = (By.XPATH, "//li[@class='ms-elem-selectable']") + self.start_hour = (By.XPATH, "//select[@id='id_hour']") + self.stop_hour = (By.XPATH, "//select[@id='id_stop_hour']") + self.daily_option = (By.XPATH, "//button[./text()='Daily']") + self.other_recipients = (By.XPATH, "//textarea[@aria-describedby='select2-id_recipient_emails-container']") + self.recipient_value = "//li[contains(@class,'select2-results__option')][.='{}']" + self.my_scheduled_reports = (By.XPATH, "//div[@data-bind='if: is_owner']/table/tbody/tr") + self.report_schedule_time = (By.XPATH, "(//div[@data-bind='if: is_owner']/table/tbody/tr/td[3])[last()]") + self.recipients_name = (By.XPATH, "(//div[@data-bind='if: is_owner']/table/tbody/tr/td[4])[last()]") + self.submit_id = (By.ID, "submit-id-submit_btn") + self.success_alert = (By.XPATH, "//div[@class='alert alert-margin-top fade in alert-success']") + self.select_all = (By.XPATH, "(//button[@data-bind='click: selectAll'])[1]") + self.delete_selected = (By.XPATH, "//a[@class='btn btn-danger']") + self.delete_scheduled_confirm = (By.XPATH, "(//button[@data-bind='click: bulkDelete'])[1]") + self.delete_success_scheduled = (By.XPATH, "//div[@class='alert alert-margin-top fade in alert-success']") + + # Submit History + self.users_box = (By.XPATH, "//span[@class='select2-selection select2-selection--multiple']") + self.search_user = (By.XPATH, "//textarea[@class='select2-search__field']") + self.select_user = (By.XPATH, "//li[contains(text(),'[Web Users]')]") + self.app_user_select = "(//li[contains(text(),'{}')])[1]" + self.application_select = (By.XPATH, "//select[@id='report_filter_form_app_id']") + self.module_select = (By.XPATH, "//select[@id='report_filter_form_module']") + self.form_select = (By.XPATH, "//select[@id='report_filter_form_xmlns']") + self.case_type_select = (By.XPATH, "//select[@id='report_filter_case_type']") + self.date_input = (By.XPATH, "//input[@id='filter_range']") + self.view_form_link = (By.XPATH, "//tbody/tr[1]/td[1]/a[.='View Form']") + self.case_name = (By.XPATH, "//td[div[contains(text(),'abc')]]") + self.submit_history_table = (By.XPATH, "//table[@id='report_table_submit_history']/tbody/tr") + self.location_values = (By.XPATH, "//tr[@class='form-data-question ']/td[2]") + + # Case List + self.search_input = (By.XPATH, "//input[@id='report_filter_search_query']") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr") + self.case_id_block = (By.XPATH, "//th[@title='_id']/following-sibling::td") + self.remove_case_owner = ( + By.XPATH, "//label[.='Case Owner(s)']//following-sibling::div//button[@aria-label='Remove item']") + self.case_owner_textarea = (By.XPATH, "//label[.='Case Owner(s)']//following-sibling::div//textarea") + self.case_owner_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.case_owner_column = (By.XPATH, "//tbody//td[3]") + + # Case List Explorer + self.edit_column = (By.XPATH, + "//div[./label[contains(.,'Columns')]]//following-sibling::div//a[@data-parent='#case-list-explorer-columns']") + self.properties_table = (By.XPATH, "//tbody[contains(@data-bind,'properties')]") + self.add_property_button = (By.XPATH, "//*[@data-bind='click: addProperty']") + self.property_name_input = (By.XPATH, "(//tbody[contains(@data-bind,'properties')]//td[2]//input)[last()]") + self.cle_case_owner_column = (By.XPATH, "//table[contains(@class,'datatable')]//tbody//td[5]") + + # Messaging History + self.communication_type_select = (By.XPATH, "//label[.='Communication Type']/following-sibling::div/select") + + # Report Case + self.report_case_links = (By.XPATH, "//li/a[contains(@title,'report case')]") + self.report_case_link = "(//li/a[contains(@title,'{}')])[1]" + self.report_form_links = (By.XPATH, "//li/a[contains(@title,'report form')]") + self.report_form_link = "(//li/a[contains(@title,'{}')])[1]" + + # Configurable Report + self.configurable_report = (By.LINK_TEXT, "Configurable Reports") + self.add_report_button = (By.XPATH, "//div[@id='hq-content']//*[contains(.,'Add Report')]") + self.edit_report_dropdown = ( + By.XPATH, "//span[contains(@class,'placeholder')][.='Edit a report or data source']") + self.report_search_input = (By.XPATH, "//input[@role='searchbox']") + self.select_report = "//li[contains(.,'{}')]/i" + self.report_dropdown = (By.XPATH, "//select[@id='select2-navigation']") + self.description_input = (By.XPATH, "//input[@id='id_description']") + self.save_button = (By.XPATH, "//button[.='Save']") + + # Daily Form Activity + self.daily_form_activity_results = (By.XPATH, "//table[@id='report_table_daily_form_stats']/tbody/tr") + self.daily_form_activity_results_cells = (By.XPATH, "//table[@id='report_table_daily_form_stats']/tbody/tr/td") + self.users_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.remove_active_worker = (By.XPATH,"//span[.='[Active Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_deactive_worker = (By.XPATH, "//span[.='[Deactivated Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.user_from_list = "//li[contains(.,'{}')]" + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + + # App Status + self.app_status_results = (By.XPATH, "//table[@class='table table-striped datatable dataTable no-footer']/tbody/tr") + self.app_status_results_cells = (By.XPATH, "//table[@class='table table-striped datatable dataTable no-footer']/tbody/tr/td") + + + def check_if_report_loaded(self): + try: + self.wait_to_click(self.apply_id) + time.sleep(10) + except (TimeoutException, NoSuchElementException): + print("Button Disabled") + try: + assert self.is_visible_and_displayed(self.report_content_id) + except (TimeoutException, AssertionError): + assert self.is_visible_and_displayed(self.custom_report_content_id) + print("Report loaded successfully!") + + def worker_activity_report(self): + self.wait_to_click(self.worker_activity_rep) + self.check_if_report_loaded() + + def daily_form_activity_report(self): + self.wait_to_click(self.daily_form_activity_rep) + self.check_if_report_loaded() + + def submissions_by_form_report(self): + self.wait_to_click(self.submissions_by_form_rep) + self.check_if_report_loaded() + + def form_completion_report(self): + self.wait_to_click(self.form_completion_rep) + self.check_if_report_loaded() + + def case_activity_report(self): + self.wait_to_click(self.case_activity_rep) + self.check_if_report_loaded() + + def completion_vs_submission_report(self): + self.wait_to_click(self.completion_vs_submission_rep) + self.check_if_report_loaded() + + def worker_activity_times_report(self): + self.wait_to_click(self.worker_activity_times_rep) + self.check_if_report_loaded() + + def project_performance_report(self): + self.wait_to_click(self.project_performance_rep) + self.check_if_report_loaded() + + def submit_history_report(self): + self.wait_to_click(self.submit_history_rep) + self.check_if_report_loaded() + + def case_list_report(self): + self.wait_to_click(self.case_list_rep) + self.check_if_report_loaded() + + def sms_usage_report(self): + self.wait_to_click(self.sms_usage_rep) + self.check_if_report_loaded() + + def messaging_history_report(self): + self.wait_to_click(self.messaging_history_rep) + date_range = self.get_last_7_days_date_range() + self.clear(self.date_input) + self.send_keys(self.date_input, date_range + Keys.TAB) + self.check_if_report_loaded() + + def message_log_report(self): + self.wait_to_click(self.message_log_rep) + self.check_if_report_loaded() + + def sms_opt_out_report(self): + self.wait_to_click(self.sms_opt_out_rep) + assert self.is_visible_and_displayed(self.report_content_id) + + def scheduled_messaging_report(self): + self.wait_to_click(self.scheduled_messaging_rep) + self.check_if_report_loaded() + + def delete_report(self): + if self.is_present(self.delete_report_xpath): + self.wait_to_click(self.delete_report_xpath) + print("Report deleted successfully!") + else: + try: + self.wait_to_click(self.edit_report_id) + except TimeoutException: + self.driver.refresh() + self.wait_to_click(self.edit_report_id) + self.wait_to_click(self.delete_report_xpath) + print("Report deleted successfully!") + self.wait_to_click(self.homepage) + + def create_report_builder_case_report(self): + self.wait_to_click(self.create_new_rep_id) + self.send_keys(self.report_name_textbox_id, self.report_name_case) + self.click(self.select_app) + self.select_by_text(self.select_source_id, self.select_source_id_case_value) + self.wait_to_click(self.next_button_id) + self.wait_to_click(self.save_and_view_button_id) + self.check_if_report_loaded() + + + def create_report_builder_form_report(self): + self.wait_to_click(self.create_new_rep_id) + self.send_keys(self.report_name_textbox_id, self.report_name_form) + self.select_by_value(self.form_or_cases, self.select_form_type_value) + self.select_by_text(self.application, UserData.village_application) + self.select_by_text(self.select_source_id, self.select_source_id_form_value) + self.wait_to_click(self.next_button_id) + self.wait_to_click(self.save_and_view_button_id) + self.check_if_report_loaded() + + def saved_report(self): + self.wait_to_click(self.case_activity_rep) + self.wait_to_click(self.save_xpath) + self.send_keys(self.new_saved_report_name, self.report_name_saved) + self.wait_to_click(self.save_confirm) + time.sleep(2) + self.js_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed(self.saved_report_created, 120) + print("Report Saved successfully!") + + + def create_scheduled_report_button(self): + self.wait_and_sleep_to_click(self.scheduled_reports_menu_xpath) + self.wait_to_click(self.create_scheduled_report) + + def scheduled_report(self): + self.create_scheduled_report_button() + try: + self.wait_to_click(self.available_reports) + except TimeoutException: + self.saved_report() + self.create_scheduled_report_button() + self.wait_to_click(self.available_reports) + self.wait_to_click(self.daily_option) + self.select_by_index(self.start_hour, 10) + self.wait_to_click(self.other_recipients) + self.send_keys(self.other_recipients, UserData.p1p2_user) + self.wait_to_click((By.XPATH, self.recipient_value.format(UserData.p1p2_user))) + selected_hour = self.get_selected_text(self.start_hour) + self.wait_to_click(self.submit_id) + assert self.is_visible_and_displayed(self.success_alert) + print("Scheduled Report Created Successfully") + return selected_hour, UserData.p1p2_user + + def verify_scheduled_report(self, time, user): + self.wait_for_element(self.my_scheduled_reports) + if len(self.find_elements(self.my_scheduled_reports)) > 0: + print("My scheduled report is present") + assert True + else: + print("No scheduled report is present") + assert False + time_text = self.get_text(self.report_schedule_time) + print(time_text) + assert time in time_text, "Scheduled Time is not matching" + recipient_text = self.get_text(self.recipients_name) + print(recipient_text) + assert user in recipient_text, "Recipient is not present" + + def delete_scheduled_and_saved_reports(self): + self.js_click(self.saved_reports_menu_link) + try: + self.click(self.delete_saved) + print("Deleted Saved Report") + except NoSuchElementException: + print("Not such report found!") + self.wait_to_click(self.scheduled_reports_menu_xpath) + try: + self.wait_to_click(self.select_all) + self.wait_to_click(self.delete_selected) + self.wait_to_click(self.delete_scheduled_confirm) + self.is_visible_and_displayed(self.delete_success_scheduled) + print("Deleted Scheduled Report") + except TimeoutException: + print("No reports available") + + def delete_saved_reports(self): + self.js_click(self.saved_reports_menu_link) + list = self.find_elements(self.all_saved_reports) + if len(list) > 0: + for items in list: + self.wait_to_click(items) + print("Deleted Saved Report") + list = self.find_elements(self.all_saved_reports) + else: + print("No saved test reports") + + def delete_report_case_links(self): + list = self.find_elements(self.report_case_links) + print(len(list)) + print(list) + if len(list) > 0: + for i in range(len(list))[::-1]: + text = list[i].text + print(i, text) + self.wait_for_element((By.XPATH, self.report_case_link.format(text))) + self.wait_to_click((By.XPATH, self.report_case_link.format(text))) + self.wait_to_click(self.edit_report_id) + self.wait_to_click(self.delete_report_xpath) + print("Deleted Saved Report") + time.sleep(2) + self.driver.refresh() + time.sleep(5) + list = self.find_elements(self.report_case_links) + + else: + print("Report deleted successfully!") + + def delete_report_form_links(self): + list = self.find_elements(self.report_form_links) + print(len(list)) + print(list) + if len(list) > 0: + for i in range(len(list))[::-1]: + text = list[i].text + print(i, text) + self.wait_for_element((By.XPATH, self.report_form_link.format(text))) + self.wait_to_click((By.XPATH, self.report_form_link.format(text))) + self.wait_to_click(self.edit_report_id) + self.wait_to_click(self.delete_report_xpath) + print("Deleted Saved Report") + time.sleep(2) + self.driver.refresh() + time.sleep(5) + list = self.find_elements(self.report_form_links) + + else: + print("Report deleted successfully!") + + + def get_last_7_days_date_range(self): + # Get today's date + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d') + + def get_todays_date_range(self): + # Get today's date + presentday = datetime.now() # or presentday = datetime.today() + return presentday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d') + + def verify_table_not_empty(self, locator): + clickable = ec.presence_of_all_elements_located(locator) + element = WebDriverWait(self.driver, 30).until(clickable, message="Couldn't find locator: " + + str(locator)) + count = len(element) + if count > 0: + print(count, " rows are present in the web table") + return True + else: + print("No rows are present in the web table") + return False + + def verify_form_data_submit_history(self, case_name, username): + print("Sleeping for sometime for the case to get registered.") + time.sleep(90) + self.wait_to_click(self.submit_history_rep) + self.wait_to_click(self.users_box) + self.send_keys(self.search_user, username) + self.wait_to_click((By.XPATH, self.app_user_select.format(username))) + self.select_by_text(self.application_select, UserData.reassign_cases_application) + self.select_by_text(self.module_select, UserData.case_list_name) + self.select_by_text(self.form_select, UserData.form_name) + date_range = self.get_todays_date_range() + self.clear(self.date_input) + self.send_keys(self.date_input, date_range + Keys.TAB) + self.wait_to_click(self.apply_id) + time.sleep(15) + self.scroll_to_bottom() + self.verify_table_not_empty(self.submit_history_table) + self.is_present_and_displayed(self.view_form_link) + form_link = self.get_attribute(self.view_form_link, "href") + print("View Form Link: ", form_link) + # self.switch_to_new_tab() + self.driver.get(form_link) + time.sleep(3) + self.page_source_contains(case_name) + assert True, "Case name is present in Submit history" + # self.driver.close() + # self.switch_back_to_prev_tab() + self.driver.back() + + def verify_form_data_case_list(self, case_name): + self.wait_to_click(self.case_list_rep) + self.wait_to_click(self.users_box) + self.wait_to_click(self.select_user) + self.send_keys(self.search_input, case_name) + self.wait_to_click(self.apply_id) + time.sleep(15) + self.scroll_to_bottom() + self.verify_table_not_empty(self.case_list_table) + self.page_source_contains(case_name) + self.wait_and_sleep_to_click((By.LINK_TEXT, str(case_name))) + # self.switch_to_next_tab() + time.sleep(3) + self.page_source_contains(case_name) + assert True, "Case name is present in Case List" + # self.driver.close() + # self.switch_back_to_prev_tab() + self.driver.back() + + def verify_app_data_submit_history(self, case_name): + print("Sleeping for sometime for the case to get registered.") + time.sleep(90) + self.wait_to_click(self.submit_history_rep) + self.wait_to_click(self.users_box) + self.send_keys(self.search_user, UserData.app_login) + self.wait_to_click((By.XPATH, self.app_user_select.format(UserData.app_login))) + self.select_by_text(self.application_select, UserData.reassign_cases_application) + self.select_by_text(self.module_select, UserData.case_list_name) + self.select_by_text(self.form_select, UserData.new_form_name) + date_range = self.get_todays_date_range() + self.clear(self.date_input) + self.send_keys(self.date_input, date_range + Keys.TAB) + self.wait_to_click(self.apply_id) + time.sleep(15) + self.scroll_to_bottom() + self.verify_table_not_empty(self.submit_history_table) + self.is_present_and_displayed(self.view_form_link) + form_link = self.get_attribute(self.view_form_link, "href") + print("View Form Link: ", form_link) + # self.switch_to_new_tab() + self.driver.get(form_link) + time.sleep(3) + self.page_source_contains(case_name) + assert True, "Case name is present in Submit history" + + def verify_updated_data_in_case_list(self, case_name, value): + self.page_source_contains(case_name) + self.wait_and_sleep_to_click((By.LINK_TEXT, str(case_name))) + time.sleep(3) + self.page_source_contains(case_name) + assert self.is_present_and_displayed( + (By.XPATH, "//div[@id='properties']//td[contains(text(),'" + value + "')]")), "Case property not updated." + print("Case is updated successfully") + case_id = self.get_text(self.case_id_block) + return case_id + + def validate_messaging_history_for_cond_alert(self, cond_alert): + self.wait_to_click(self.messaging_history_rep) + date_range = self.get_todays_date_range() + self.clear(self.date_input) + self.send_keys(self.date_input, date_range + Keys.TAB) + time.sleep(2) + self.deselect_all(self.communication_type_select) + time.sleep(2) + self.select_by_text(self.communication_type_select, UserData.communication_type) + self.check_if_report_loaded() + self.scroll_to_bottom() + print(cond_alert) + list_alerts = self.driver.find_elements(By.XPATH, "//td[.='" + cond_alert + "']/following-sibling::td[3]") + print(len(list_alerts)) + if len(list_alerts) > 0: + for i in range(len(list_alerts)): + text = list_alerts[i].text + print(text) + if "Completed" in text: + assert True + elif "Internal Server Error" in text: + assert False + else: + print("Alert status is not Completed but has no Internal Server Error") + + def check_for_case_list_owner(self, url): + if 'www' in url: + owner = UserData.appiumtest_owner_id_prod + else: + owner = UserData.appiumtest_owner_id + self.wait_to_click(self.case_list_rep) + self.wait_for_element(self.remove_case_owner) + self.wait_to_click(self.remove_case_owner) + self.wait_to_click(self.case_owner_textarea) + self.send_keys(self.case_owner_textarea, UserData.app_login) + self.wait_for_element((By.XPATH, self.case_owner_list_item.format(UserData.app_login))) + self.wait_to_click((By.XPATH, self.case_owner_list_item.format(UserData.app_login))) + self.wait_to_click(self.apply_id) + time.sleep(15) + self.scroll_to_bottom() + list_of_owner = self.find_elements(self.case_owner_column) + print(len(list_of_owner)) + if len(list_of_owner) > 0: + for i in range(len(list_of_owner)): + text = list_of_owner[i].text + print(text) + assert text == owner or text == UserData.user_group, "Owner does not match" + self.check_if_html(text) + + def check_for_case_list_explorer_owner(self, url): + if 'www' in url: + owner = UserData.appiumtest_owner_id_prod + else: + owner = UserData.appiumtest_owner_id + self.wait_to_click(self.case_list_explorer) + time.sleep(5) + self.wait_for_element(self.edit_column) + self.wait_to_click(self.edit_column) + self.wait_for_element(self.properties_table) + self.wait_to_click(self.add_property_button) + self.wait_to_click(self.property_name_input) + self.send_keys(self.property_name_input, "owner_name") + time.sleep(1) + ActionChains(self.driver).key_down(Keys.ENTER).send_keys(Keys.TAB).perform() + self.scroll_to_element(self.remove_case_owner) + self.wait_to_click(self.remove_case_owner) + self.wait_to_click(self.case_owner_textarea) + self.send_keys(self.case_owner_textarea, UserData.app_login) + self.wait_for_element((By.XPATH, self.case_owner_list_item.format(UserData.app_login))) + self.wait_to_click((By.XPATH, self.case_owner_list_item.format(UserData.app_login))) + self.wait_to_click(self.apply_id) + time.sleep(15) + self.scroll_to_bottom() + list_of_owner = self.find_elements(self.cle_case_owner_column) + print(len(list_of_owner)) + if len(list_of_owner) > 0: + for i in range(len(list_of_owner)): + text = list_of_owner[i].text + print(text) + assert text == owner or text == UserData.user_group, "Owner does not match" + self.check_if_html(text) + + def check_if_html(self, text): + re_is_html = re.compile(r"(?:)|(?:<[^<]+/>)") + result = re_is_html.search(text) + if result: + print("Owner name has html tags") + assert False + else: + print("No html tag present") + assert True + + def configure_add_report(self): + self.wait_to_click(self.configurable_report) + time.sleep(10) + self.wait_for_element(self.report_dropdown, 300) + self.wait_to_click(self.edit_report_dropdown) + self.wait_for_element(self.report_search_input) + self.send_keys(self.report_search_input, self.report_name_form) + self.wait_to_click((By.XPATH, self.select_report.format(self.report_name_form))) + # self.select_by_text(self.report_dropdown, self.report_name_form) + time.sleep(10) + # self.wait_for_element(self.description_input, 300) + assert self.is_present_and_displayed(self.description_input, 300), "Edit screen is not displayed" + self.wait_to_clear_and_send_keys(self.description_input, "editing " + self.report_name_form) + self.scroll_to_element(self.save_button) + self.wait_to_click(self.save_button) + time.sleep(10) + assert self.is_present_and_displayed(self.success_alert, 300), "Report not saved successfully" + # self.wait_for_element(self.success_alert, 400) + + def verify_only_permitted_report(self, report_name): + self.wait_to_click(self.reports_menu_id) + assert self.is_present_and_displayed((By.LINK_TEXT, report_name)) + self.wait_to_click((By.LINK_TEXT, report_name)) + assert self.is_present_and_displayed(self.apply_id), "Report page not accessible" + print("Report page is accessible") + + def export_daily_form_activity_to_excel(self): + self.wait_to_click(self.daily_form_activity_rep) + try: + self.wait_for_element(self.remove_active_worker) + count = self.find_elements(self.remove_buttons) + print(len(count)) + for i in range(len(count)): + count[0].click() + time.sleep(2) + if len(count) != 1: + ActionChains(self.driver).send_keys(Keys.TAB).perform() + time.sleep(2) + count = self.find_elements(self.remove_buttons) + # self.wait_to_click(self.users_field) + self.send_keys(self.users_field, UserData.app_login) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.app_login))) + time.sleep(2) + ActionChains(self.driver).send_keys(Keys.TAB).perform() + self.wait_to_click(self.apply_id) + time.sleep(10) + except (TimeoutException, NoSuchElementException): + print("Button Disabled") + try: + assert self.is_visible_and_displayed(self.report_content_id) + except (TimeoutException, AssertionError): + assert self.is_visible_and_displayed(self.custom_report_content_id) + print("Report loaded successfully!") + self.wait_for_element(self.daily_form_activity_results) + col = self.find_elements(self.daily_form_activity_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + # web_data = pd.DataFrame(list) + self.wait_to_click(self.export_to_excel) + self.wait_for_element(self.export_success) + print("Export to excel successful") + return list + + def compare_web_with_email(self, link, web_data): + print(link) + print(web_data) + self.driver.get(link) + time.sleep(10) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + new_data = new_data[new_data["Username"].str.contains("Total") == False] + print(new_data.values) + list = [] + list.extend(new_data.values.tolist()) + list = list[0] + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + web_data[i] + + def export_app_status_to_excel(self): + self.wait_to_click(self.application_status_rep) + try: + self.wait_for_element(self.remove_active_worker) + count = self.find_elements(self.remove_buttons) + print(len(count)) + for i in range(len(count)): + count[0].click() + time.sleep(2) + if len(count) != 1: + ActionChains(self.driver).send_keys(Keys.TAB).perform() + time.sleep(2) + count = self.find_elements(self.remove_buttons) + + # self.wait_to_click(self.users_field) + self.send_keys(self.users_field, UserData.app_login) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.app_login))) + self.wait_to_click(self.apply_id) + time.sleep(10) + except (TimeoutException, NoSuchElementException): + print("Button Disabled") + try: + assert self.is_visible_and_displayed(self.report_content_id) + except (TimeoutException, AssertionError): + assert self.is_visible_and_displayed(self.custom_report_content_id) + print("Report loaded successfully!") + self.wait_for_element(self.app_status_results) + col = self.find_elements(self.app_status_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + # web_data = pd.DataFrame(list) + self.wait_to_click(self.export_to_excel) + self.wait_for_element(self.export_success) + print("Export to excel successful") + return list + + def compare_app_status_web_with_email(self, link, web_data): + print(link) + print(web_data) + self.driver.get(link) + time.sleep(10) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + list = [] + list.extend(new_data.values.tolist()) + list = list[0] + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + if i == 1 or i == 2: + print("Not comparing", html.unescape(str(list[i])), " with ", str(web_data[i])) + else: + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + web_data[i] + + def verify_form_in_submit_history(self, app_name, lat, lon): + print("Sleeping for sometime for the case to get registered.") + time.sleep(140) + self.wait_to_click(self.submit_history_rep) + self.wait_to_click(self.users_box) + self.send_keys(self.search_user, UserData.app_login) + self.wait_to_click((By.XPATH, self.app_user_select.format(UserData.app_login))) + self.select_by_text(self.application_select, app_name) + self.select_by_text(self.module_select, UserData.case_list_name) + date_range = self.get_todays_date_range() + self.clear(self.date_input) + self.send_keys(self.date_input, date_range + Keys.TAB) + self.wait_to_click(self.apply_id) + time.sleep(15) + self.scroll_to_bottom() + self.verify_table_not_empty(self.submit_history_table) + self.is_present_and_displayed(self.view_form_link) + form_link = self.get_attribute(self.view_form_link, "href") + print("View Form Link: ", form_link) + # self.switch_to_new_tab() + self.driver.get(form_link) + time.sleep(3) + text = self.get_text(self.location_values) + text = text.split(" ") + result_lat = self.format_number(abs(float(text[0])), 5) + result_lon = self.format_number(abs(float(text[1])), 5) + print(result_lat, result_lon) + assert result_lat in lat and result_lon in lon, "Mismatch" + + def format_number(self, n, digits): + formatter = '{:.' + '{}'.format(digits) + 'f}' + x = round(n, digits) + return formatter.format(x) \ No newline at end of file diff --git a/ElasticSearchTests/testPages/submissions_by_forms/__init__.py b/ElasticSearchTests/testPages/submissions_by_forms/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/submissions_by_forms/submissions_by_form_page.py b/ElasticSearchTests/testPages/submissions_by_forms/submissions_by_form_page.py new file mode 100644 index 000000000..581084de6 --- /dev/null +++ b/ElasticSearchTests/testPages/submissions_by_forms/submissions_by_form_page.py @@ -0,0 +1,1120 @@ +import html +import os +import time + +import dateutil.relativedelta +import pandas as pd + +from datetime import datetime, timedelta, date +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from selenium.webdriver import ActionChains + +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from ElasticSearchTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec + +""""Contains test page elements and functions related to the Reports module""" + + +class SubmissionsByFormPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.sub_by_form_rep = (By.LINK_TEXT, "Submissions By Form") + self.sub_by_form_TITLE = "Submissions By Form - CommCare HQ" + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + self.homepage = (By.XPATH, ".//a[@href='/homepage/']") + self.date_range_error = (By.XPATH, "//td[contains(.,'You are limited to a span of 90 days,')]") + + self.form_activity_results = (By.XPATH, "//table[@id='report_table_submissions_by_form']/tbody/tr") + self.form_activity_results_cells = ( + By.XPATH, "//table[@id='report_table_submissions_by_form']/tbody/tr[not(contains(.,'All Users'))]/td") + self.all_users_results_cells = ( + By.XPATH, "(//tfoot)[2]/tr/td") + self.users_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.filter_dates_by = (By.XPATH, "//select[@id='report_filter_sub_time']") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.user_from_list = "//li[contains(.,'{}')]" + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + self.user_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_submissions_by_form']/div[contains(.,'User')])[1]") + self.all_forms_column = ( + By.XPATH, + "(//thead/tr/th[@aria-controls='report_table_submissions_by_form']/div[contains(.,'All Forms')])[1]") + self.app_mod_form_column = "(//thead/tr/th[@aria-controls='report_table_submissions_by_form']/div[contains(.,'{}')])[1]" + self.users_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.users_list = (By.XPATH, "//ul[contains(@class,'select2-results__options')]/li") + self.users_list_empty = ( + By.XPATH, "//ul[contains(@id,'select2-emw-bi-results')]/li[.='The results could not be loaded.']") + + self.date_input = (By.XPATH, "//input[@id='filter_range']") + self.date_range_type = "//li[@data-range-key='{}']" + self.column_names = "(//thead/tr/th[@aria-controls='report_table_submissions_by_form']/div[@data-title='{}'])[1]" + self.column_group_names = "(//thead/tr/th//strong[.='{}'])[1]" + self.user_names_column_list = (By.XPATH, "//table[@id='report_table_submissions_by_form']//tbody//td[1]") + self.last_submission_column_list = (By.XPATH, "//table[@id='report_table_submissions_by_form']//tbody//td[4]") + self.result_table = (By.XPATH, "(//div[@id='report-content']//table//tbody//td[1])[1]") + self.results_rows = (By.XPATH, "//tbody/tr") + self.result_rows_names = "//table[@id='report_table_submissions_by_form']//tbody/tr/td[1]//a[contains(.,'{}')]" + self.hide_filters_options = (By.XPATH, "//a[.='Hide Filter Options']") + self.show_filters_options = (By.XPATH, "//a[.='Show Filter Options']") + self.user_sort = ( + By.XPATH, + "//div[@class='DTFC_LeftWrapper']//text()[contains(.,'User')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon']") + self.active_cases_column_list = (By.XPATH, "//table[@id='report_table_submissions_by_form']//tbody//td[7]") + self.total_cases_shared_column_list = ( + By.XPATH, "//table[@id='report_table_submissions_by_form']//tbody//td[8]") + self.column_name_headers = "//table[@id='report_table_submissions_by_form']//thead//th/div/div[contains(.,'{}')]" + + # Pagination + self.page_list_dropdown = (By.XPATH, "//select[@name='report_table_submissions_by_form_length']") + self.table_info = (By.XPATH, "//div[@id='report_table_submissions_by_form_info']") + self.prev_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='prev']/a") + self.next_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='next']/a") + self.prev_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='prev disabled']/a") + self.next_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='next disabled']/a") + self.page_button = "//ul[@class='pagination']/li/a[.='{}']" + self.pagination_list = (By.XPATH, "//ul[@class='pagination']/li/a") + + # Custom date selector + self.from_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='monthselect']") + self.from_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='yearselect']") + self.from_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + + self.to_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='monthselect']") + self.to_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='yearselect']") + self.to_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + self.apply_date = ( + By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Apply']") + self.remove_active_worker = (By.XPATH, + "//span[.='[Active Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + self.remove_deactive_worker = (By.XPATH, + "//span[.='[Deactivated Mobile Workers]']//preceding-sibling::button[@class='select2-selection__choice__remove']") + + # Save Report and Favorites + self.favorite_button = (By.XPATH, "//button[contains(.,'Favorites')]") + self.empty_fav_list = (By.XPATH, '//a[.="You don\'t have any favorites"]') + self.saved_fav = "//a[contains(.,'{}')][contains(@data-bind,'text: name')]" + self.save_config_button = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.name_field = (By.XPATH, "//input[@data-bind='value: name']") + self.description_field = (By.XPATH, "//textarea[@data-bind='value: description']") + self.date_range_field_select = (By.XPATH, "//select[@data-bind='value: date_range']") + self.save_report_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Save']") + self.try_again_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Try Again']") + self.report_save_error = ( + By.XPATH, "//div[.='Some required fields are missing. Please complete them before saving.']") + self.cancel_report_button = (By.XPATH, "//div/a[.='Cancel']") + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = "//a[text()='{}']" + self.delete_saved = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + + # Case Type Verify + self.case_created_column = (By.XPATH, "//table[@id='report_table_submissions_by_form']//tbody//td[5]//a") + self.case_created_title = (By.XPATH, "//table[@id='report_table_submissions_by_form']//tbody//td[5]//span") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr/td[1]") + self.case_list_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Case List')]") + self.case_list_table_info = (By.XPATH, "//div[@id='report_table_case_list_info']") + self.case_list_page_dropdown = (By.XPATH, "//select[@name='report_table_case_list_length']") + + # Email report + self.email_report_btn = (By.XPATH, "//a[@id='email-report']") + self.email_subject_field = (By.XPATH, "//input[@id='id_subject']") + self.email_form_cancel_btn = (By.XPATH, "//input[@id='button-id-close']") + self.send_email_btn = (By.XPATH, "//input[@id='submit-id-submit_btn']") + self.email_success_message = (By.XPATH, "//*[.='Report successfully emailed']") + + # Application form section + self.application_dropdown = (By.XPATH, "//select[@id='report_filter_form_app_id']") + self.module_dropdown = (By.XPATH, "//select[@id='report_filter_form_module']") + self.form_dropdown = (By.XPATH, "//select[@id='report_filter_form_xmlns']") + self.show_adv_options = (By.XPATH, "//input[@name='show_advanced']") + self.known_forms = (By.XPATH, "//input[@id='report_filter_form_unknown_hide']") + self.unknown_forms = (By.XPATH, "//input[@id='report_filter_form_unknown_show']") + self.unknown_form_dropdown = (By.XPATH, "//select[@id='report_filter_form-unknown_xmlns']") + self.application_type_dropdown = (By.XPATH, "//select[@id='report_filter_form_status']") + + # Submit History Verification + self.total_form_counts = "//td[contains(.,'{}')]//following-sibling::td[last()]" + self.filter_column_name = "(//thead//th[@aria-controls='report_table_submit_history'][3]/div[contains(.,'{}')])[1]" + self.submit_history_table_info = (By.XPATH, "//div[@id='report_table_submit_history_info']") + self.empty_table = (By.XPATH, "//tr/td[contains(.,'No data available to display.')]") + self.submit_history_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Submit History')]") + + def hide_filters(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.hide_filters_options) + self.click(self.hide_filters_options) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_field, 10), "User field is still present" + assert not self.is_visible_and_displayed(self.application_dropdown, 10), "Application dropdown is still present" + assert not self.is_visible_and_displayed(self.show_adv_options, + 10), "Show Advance Options checkbox is still present" + assert not self.is_visible_and_displayed(self.date_input, 10), "Date Range field is still present" + assert not self.is_visible_and_displayed(self.filter_dates_by, 10), "Filter Dates By field is still present" + assert self.is_present(self.show_filters_options), "Show Filters Options is not present" + print("All filters are hidden!") + + def show_filters(self): + self.wait_for_element(self.show_filters_options) + self.click(self.show_filters_options) + time.sleep(2) + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + assert self.is_present(self.show_adv_options), "Show Advance Options checkbox is not present" + assert self.is_present(self.filter_dates_by), "Filter Dates By field is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_sub_by_form_page_fields(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Submissions By Form page." + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + assert self.is_present(self.show_adv_options), "Show Advance Options checkbox is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.filter_dates_by), "Filter Dates By field is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def verify_table_columns(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Submissions By Form page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + column_name = UserData.reassign_cases_application + " > " + list(UserData.reasign_modules_forms.keys())[ + 1] + " > " + UserData.reasign_modules_forms[list(UserData.reasign_modules_forms.keys())[1]][0] + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.user_column), "Username Column not present" + assert self.is_present(self.all_forms_column), "All Forms Column not present" + assert self.is_present( + (By.XPATH, self.app_mod_form_column.format(column_name))), "Form Name Column not present: " + column_name + + def select_application_and_forms(self, app, module, form): + self.wait_for_element(self.application_dropdown) + text = self.get_selected_text(self.application_dropdown) + print(text) + assert UserData.default_app_mod_form[0] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form[0] + print(UserData.default_app_mod_form[0] + " is present as default value") + self.select_by_text(self.application_dropdown, app) + self.wait_for_element(self.module_dropdown) + text = self.get_selected_text(self.module_dropdown) + print(text) + assert UserData.default_app_mod_form[1] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form[1] + print(UserData.default_app_mod_form[1] + " is present as default value") + mod_list = [UserData.default_app_mod_form[1]] + list(UserData.reasign_modules_forms.keys()) + self.verify_dropdown_options(self.module_dropdown, mod_list) + self.select_by_text(self.module_dropdown, module) + self.wait_for_element(self.form_dropdown) + text = self.get_selected_text(self.form_dropdown) + print(text) + assert UserData.default_app_mod_form[2] in text, "Values mismatch: " + text + " and " + \ + UserData.default_app_mod_form[2] + print(UserData.default_app_mod_form[2] + " is present as default value") + form_list = [UserData.default_app_mod_form[2]] + UserData.reasign_modules_forms[module] + self.verify_dropdown_options(self.form_dropdown, form_list) + self.select_by_text(self.form_dropdown, form) + + def verify_dropdown_options(self, locator, list_to_compare): + print("List to compare: ", list_to_compare) + assert list_to_compare == self.get_all_dropdown_options(locator), "Dropdown does not have all the options" + print("All module/form options are present in the dropdown") + + def verify_user_lookup_table(self): + self.wait_to_click(self.users_field) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_list_empty, 10), "User List is not empty" + list = self.find_elements(self.users_list) + print(len(list)) + assert int(len(list)) >= 1 + print("A Look up for users is successfully loaded") + + def date_generator(self, start, end): + start_date = parse(start) + end_date = parse(end) # perhaps date.now() + date_list = [] + delta = end_date - start_date # returns timedelta + + for i in range(delta.days + 1): + day = start_date + timedelta(days=i) + day = str(day.strftime('%Y-%m-%d')) + date_list.append(day) + print(day) + return date_list + + def remove_default_users(self): + self.wait_for_element(self.users_field) + count = self.find_elements(self.remove_buttons) + print(len(count)) + for i in range(len(count)): + count[0].click() + time.sleep(2) + if len(count) != 1: + ActionChains(self.driver).send_keys(Keys.TAB).perform() + time.sleep(2) + count = self.find_elements(self.remove_buttons) + + def verify_users_in_the_group(self): + list = self.find_elements(self.results_rows) + if len(list) > 0: + for item in UserData.automation_group_users: + assert self.is_present((By.XPATH, self.result_rows_names.format( + item))), "Group user " + item + " is not present in results." + print("Group User " + item + " is present in results.") + + def sub_by_form_pagination_list(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + pages = self.find_elements(self.pagination_list) + pages_count = len(pages) - 2 + print("Total Pages: ", pages_count) + first_page = pages[1].text + last_page = pages[-2].text + if pages_count > 1: + assert self.is_present(self.prev_page_button_disabled), "Previous button is not disabled." + print("Previous button disabled correctly") + print("Clicking on page " + last_page) + self.wait_to_click((By.XPATH, self.page_button.format(last_page))) + time.sleep(15) + assert self.is_present(self.next_page_button_disabled), "Next button is not disabled." + print("Next button disabled correctly") + time.sleep(5) + print("Clicking on page " + first_page) + self.wait_to_click((By.XPATH, self.page_button.format(first_page))) + time.sleep(15) + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + self.wait_to_click(self.next_page_button) + time.sleep(5) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print(list1_names, list2_names) + assert list1_names != list2_names, "Both Pages have same values" + print("Next button functioning correctly.") + self.wait_to_click(self.prev_page_button) + time.sleep(5) + list3 = self.find_elements(self.user_names_column_list) + list3_names = list() + for item in list3: + list3_names.append(item.text) + print(list1_names, list2_names, list3_names) + assert list1_names == list3_names and list2_names != list3_names, "Page contains same data as the previous" + print("Prev button functioning correctly.") + else: + print("Not enough users are present.") + assert self.is_present(self.prev_page_button_disabled) + assert self.is_present(self.next_page_button_disabled) + print("Both Previous and Next Page buttons are disabled correctly.") + + def verify_pagination_dropdown(self): + info = self.get_text(self.table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + + for item in UserData.pagination: + self.select_by_value(self.page_list_dropdown, item) + time.sleep(10) + list = self.find_elements(self.user_names_column_list) + print(len(list)) + if int(info[-2]) < int(item): + assert int(len(list)) == int(info[-2]), "List does not have all records." + print("Records displayed correctly for " + item) + elif int(info[-2]) >= int(item): + assert int(len(list)) == int(item), "List does not have all records." + print("Records displayed correctly for " + item) + else: + print("No records to display") + + def verify_sorted_list(self): + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + sorted_list = sorted(list1_names) + assert list1_names == sorted_list, "List is not sorted" + print("List is in ascending order") + self.wait_to_click(self.user_sort) + time.sleep(15) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + rev_list = list(reversed(sorted_list)) + assert list2_names == rev_list, "List is not sorted" + print("List is in descending order") + + def value_date_range_7_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return str(week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), week_ago.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_30_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + pastday = presentday - timedelta(30) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_last_month(self): + last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) + start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) + print(start_day_of_prev_month, last_day_of_prev_month) + return str(start_day_of_prev_month.strftime('%Y-%m-%d') + " to " + last_day_of_prev_month.strftime( + '%Y-%m-%d')), start_day_of_prev_month.strftime( + '%Y-%m-%d'), last_day_of_prev_month.strftime('%Y-%m-%d') + + def sub_by_form_search(self, date_range=UserData.date_range[0]): + date_string = start_date = end_date = '' + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Submissions By Form page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(date_range))) + text = self.get_attribute(self.date_input, "value") + print(text) + if date_range == UserData.date_range[0]: + date_string, start_date, end_date = self.value_date_range_7_days() + elif date_range == UserData.date_range[1]: + date_string, start_date, end_date = self.value_date_range_last_month() + elif date_range == UserData.date_range[2]: + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + date_range) + + def date_validator(self, date_value, start_date, end_date): + dt = parse(date_value) + st = parse(start_date) + et = parse(end_date) + print(dt, st, et) + if st <= dt <= et: + assert True, "Date outside date range" + print("within range") + else: + print("not within range") + assert False + + def sub_by_form_search_custom_date(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Submissions By Form page." + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 5) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string + Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present_and_displayed(self.date_range_error), "Date Range Error not displayed" + print("Date Range error correctly displayed") + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Submissions By Form page." + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.select_date_from_picker(start_date, end_date) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + list_of_columns = self.date_generator(start_date, end_date) + self.verify_date_column_name_headers(list_of_columns) + print("Dates are with in range for " + UserData.date_range[3]) + + def get_custom_dates_past(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + pastday = presentday - relativedelta(days=days, months=months, years=years) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def get_custom_dates_future(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + futureday = presentday + relativedelta(days=days, months=months, years=years) + return str(presentday.strftime('%Y-%m-%d') + " to " + futureday.strftime('%Y-%m-%d')), presentday.strftime( + '%Y-%m-%d'), futureday.strftime('%Y-%m-%d') + + def select_date_from_picker(self, start_date, end_date): + start_date = parse(start_date) + start_day = str(start_date.day) + start_month = str(start_date.month - 1) + start_year = str(start_date.year) + end_date = parse(end_date) + end_day = str(end_date.day) + end_month = str(end_date.month - 1) + end_year = str(end_date.year) + self.wait_for_element(self.from_month) + self.select_by_value(self.from_year, start_year) + time.sleep(2) + self.select_by_value(self.from_month, start_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.from_date.format(start_day))) + time.sleep(2) + self.wait_for_element(self.to_month) + self.select_by_value(self.to_year, end_year) + time.sleep(2) + self.select_by_value(self.to_month, end_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.to_date.format(end_day))) + time.sleep(2) + self.wait_to_click(self.apply_date) + + def sub_by_form_save_report(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + date_string, start_date, end_date = self.value_date_range_7_days() + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + time.sleep(10) + report_name = "Saved Submissions By Form Report " + fetch_random_string() + self.verify_favorite_empty(report_name) + self.save_report_donot_save(report_name) + report = self.save_report(report_name) + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + self.verify_favorite_created(report) + time.sleep(10) + self.verify_users_in_the_group() + self.delete_saved_report(report) + self.wait_to_click(self.sub_by_form_rep) + self.verify_favorite_empty(report_name) + + def verify_favorite_empty(self, report=None): + self.wait_to_click(self.favorite_button) + if report == None: + assert self.is_visible_and_displayed(self.empty_fav_list), "Favorites Already Present" + else: + assert not self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report)), + 30), "Favorite is already Present" + print("No Favorites yet.") + + def verify_favorite_created(self, report): + self.wait_to_click(self.favorite_button) + assert not self.is_visible_and_displayed(self.empty_fav_list, 10), "Favorites Already Present" + assert self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report))), "Favorite Not Present" + print("Favorites added.") + self.wait_to_click((By.XPATH, self.saved_fav.format(report))) + + def delete_saved_report(self, report): + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 120) + print("Report Present!") + self.click((By.XPATH, self.delete_saved.format(report))) + print("Deleted Saved Report") + time.sleep(5) + self.driver.refresh() + assert not self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 20) + print("Deleted Report Successfully") + + def save_report_donot_save(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.cancel_report_button) + time.sleep(2) + assert not self.is_visible_and_displayed(self.name_field, 10), "Save Report Form not closed" + print("Save Report Form is closed") + + def save_report(self, report_name): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + self.clear(self.name_field) + self.wait_to_click(self.save_report_button) + time.sleep(3) + assert self.is_present(self.report_save_error), "Error not displayed" + print("Error is correctly displayed") + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.try_again_button) + time.sleep(2) + self.driver.refresh() + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report_name)), 120) + print("Report Saved successfully!") + print("Report name: ", report_name) + return report_name + + def verify_case_type_data(self): + case_type_list = self.find_elements(self.case_created_column) + if len(case_type_list) > 0: + for item in case_type_list: + text = item.text + print("Cases created ", text) + if text == '0': + print("No Cases were created withing the given range") + else: + self.wait_to_click(item) + self.switch_to_next_tab() + time.sleep(10) + self.wait_for_element(self.case_list_table_title, 200) + self.scroll_to_bottom() + info = self.get_text(self.case_list_table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert info[-2] == text, "Case created count mismatch" + print("Cases created count matched") + self.select_by_value(self.case_list_page_dropdown, '100') + time.sleep(10) + cases = self.find_elements(self.case_list_table) + if len(cases) > 0: + for case in cases: + name = case.text + assert name == UserData.case_reassign, "Case Type mismatch" + print("Case Type matching") + time.sleep(2) + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def export_sub_by_form_to_excel(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_users_in_the_group() + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list_col = [] + for c in col: + list_col.append(c.text) + print(list_col) + self.wait_to_click(self.export_to_excel) + print("Export to excel successful") + print("sleeping for sometime for the download to complete") + time.sleep(15) + return list_col + + def compare_sbf_with_email(self, web_data): + print(web_data) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + print(new_data.values) + ext_list = [] + ext_list.extend(new_data.values.tolist()) + list = [] + for i in range(len(ext_list))[:-1]: + list += ext_list[i] + print("List New: ", list) + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]) or html.unescape(str(list[i])) in str(web_data[i]), \ + "Comparison failed for " + list[i] + " and " + web_data[i] + + def export_sub_by_form_email(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Submissions By Form page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list_col = [] + for c in col: + list_col.append(c.text) + print(list_col) + footer = self.find_elements(self.all_users_results_cells) + list_ft = [] + for f in footer: + list_ft.append(f.text) + print(list_ft) + list_col.extend(list_ft) + subject = UserData.email_sub_by_form_report + self.email_report_form_not_save(subject) + self.email_report_form(subject) + print("Export to excel successful") + + return list_col, subject + + def email_report_form_not_save(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.email_form_cancel_btn) + print("Email report form closed properly") + + def email_report_form(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.send_email_btn) + assert self.is_visible_and_displayed(self.email_success_message), "Email report not sent successfully" + print("Email report sent successfully") + + def compare_sbf_with_html_table(self, table_data, web_data): + list = table_data + print("Table data rows: ", len(web_data), "Web data rows: ", len(list)) + print("Table List: ", web_data) + print("Web list: ", list) + assert len(web_data) == len(list), "Data in Both Email Body and Searched results do not match" + print("Both Email Body and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def sub_by_form_users_active(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_active_worker) + assert not self.is_present(self.remove_active_worker), "Active Mobile Worker is still not removed" + print("Active Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[0]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[0]))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert not self.is_present((By.XPATH, self.result_rows_names.format( + UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is present in the active worker list." + print("All Active users are present") + + def sub_by_form_users_deactivated(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_to_click(self.remove_deactive_worker) + assert not self.is_present(self.remove_deactive_worker), "Deactivated Mobile Worker is still not removed" + print("Deactivated Mobile Worker is removed successfully") + self.driver.refresh() + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[1]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[1]))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.select_by_value(self.page_list_dropdown, UserData.pagination[3]) + time.sleep(10) + assert self.is_present((By.XPATH, self.result_rows_names.format( + UserData.deactivated_user))), "Deactivated user " + UserData.deactivated_user + " is not present in the Deactivated worker list." + print("All Deactivated users are present") + + def verify_assigned_cases_count(self, actives, totals): + print("Sleeping for some time for the cases to be assigned") + time.sleep(60) + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + active_cases = self.find_elements(self.active_cases_column_list) + actives_new = [] + for items in active_cases: + actives_new.append(items.text) + total_cases = self.find_elements(self.total_cases_shared_column_list) + totals_new = [] + for items in total_cases: + totals_new.append(items.text) + print("Active Case: ", actives_new) + print("Total shared case: ", totals_new) + for i in range(len(actives_new)): + assert int(actives[i]) - 10 == actives_new[i], "Active Cases not reduced" + print("Active cases reduced") + for i in range(len(totals_new)): + assert int(totals[i]) - 10 == totals_new[i], "Active Cases not reduced" + print("Active cases reduced") + print("Cases successfully assigned") + + def filter_dates_and_verify(self, filter): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + + self.select_by_text(self.filter_dates_by, filter) + date_string, start_date, end_date = self.get_custom_dates_past(20, 0, 0) + self.clear(self.date_input) + self.send_keys(self.date_input, date_string + Keys.TAB) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in UserData.automation_group_users: + count = self.get_text((By.XPATH, self.total_form_counts.format(items))) + print(count) + time.sleep(1) + self.js_click((By.XPATH, self.result_rows_names.format(items))) + time.sleep(15) + self.wait_for_element(self.submit_history_table_title) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + assert filter == self.get_selected_text(self.filter_dates_by), "Date Filter mismatched" + print("Date Filter matched") + assert UserData.reassign_cases_application == self.get_selected_text( + self.application_dropdown), "Application mismatched" + print("Application matched") + assert list(UserData.reasign_modules_forms.keys())[1] == self.get_selected_text( + self.module_dropdown), "Application mismatched" + print("Application matched") + assert UserData.reasign_modules_forms[list(UserData.reasign_modules_forms.keys())[1]][ + 0] == self.get_selected_text( + self.form_dropdown), "Application mismatched" + print("Application matched") + assert date_string == self.get_attribute(self.date_input, "value"), "Date Range mismatched" + print("Date Range matched") + assert self.is_present((By.XPATH, self.filter_column_name.format(filter))), "Incorrect column present" + print("Correct Column present") + self.scroll_to_bottom() + time.sleep(2) + # info = self.get_text(self.submit_history_table_info) + # print(info) + # info = str(info).split(" ") + # print("Total records: ", info[-2]) + # assert count == info[-2], "Form counts not matching" + # print("Form Count matching") + # if count == '0': + # assert self.is_present(self.empty_table) + # print("Correct value displayed") + time.sleep(5) + self.driver.back() + + def advanced_options(self): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_for_element(self.apply_id) + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.daily_form_groups[0]) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.daily_form_groups[0]))) + time.sleep(1) + self.wait_to_click(self.show_adv_options) + assert self.is_selected(self.show_adv_options), "Show Advanced Options is not selected" + print("Show Advanced Option is successfully selected") + time.sleep(2) + assert self.is_present(self.known_forms), "Known Forms option not present" + assert self.is_present(self.unknown_forms), "Unknown Forms option not present" + assert self.is_present(self.application_type_dropdown), "Application Type dropdown not present" + active_apps, deleted_apps = self.known_forms_options() + self.unknown_forms_options(active_apps, deleted_apps) + self.wait_to_click(self.show_adv_options) + assert not self.is_selected(self.show_adv_options), "Show Advanced Options is still selected" + time.sleep(2) + assert not self.is_visible_and_displayed(self.known_forms, 10), "Known Forms option still present" + assert not self.is_visible_and_displayed(self.unknown_forms, 10), "Unknown Forms option still present" + print("All Show Advanced Options are working correctly") + + def known_forms_options(self): + if not self.is_selected(self.known_forms): + self.wait_to_click(self.known_forms) + assert self.is_selected(self.known_forms), "Known Forms radio button is not selected" + else: + assert self.is_selected(self.known_forms), "Known Forms radio button is not selected" + + self.verify_dropdown_options(self.application_type_dropdown, UserData.app_type_list) + self.select_by_text(self.application_type_dropdown, UserData.app_type_list[0]) + time.sleep(2) + assert not self.is_visible_and_displayed(self.application_dropdown, 10), "Application dropdown is still present" + print("Application dropdown successfully disappeared after selecting option ", UserData.app_type_list[0]) + self.select_by_text(self.application_type_dropdown, UserData.app_type_list[2]) + time.sleep(2) + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + list_app_active = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app_active[1:]: + assert "[Deleted Application]" in items, "Not a Deleted Application option" + print("All Deleted Application present") + self.select_by_text(self.application_type_dropdown, UserData.app_type_list[1]) + time.sleep(2) + assert self.is_present(self.application_dropdown), "Application dropdown is not present" + list_app_deleted = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app_deleted[1:]: + assert "[Deleted Application]" not in items, "Deleted Application is present in the dropdown" + print("No Deleted Application present") + self.select_application_and_forms(UserData.reassign_cases_application, + list(UserData.reasign_modules_forms.keys())[1], + UserData.reasign_modules_forms[ + list(UserData.reasign_modules_forms.keys())[1]][0]) + print("Correct Modules and Forms are present") + return list_app_active, list_app_deleted + + def unknown_forms_options(self, active, deleted): + if not self.is_selected(self.unknown_forms): + self.wait_to_click(self.unknown_forms) + assert self.is_selected(self.unknown_forms), "Unknown Forms radio button is not selected" + else: + assert self.is_selected(self.unknown_forms), "Unknown Forms radio button is not selected" + + assert self.is_visible_and_displayed(self.unknown_form_dropdown), "Unknown forms dropdown is not present" + print("Application dropdown successfully disappeared after selecting option ", UserData.app_type_list[0]) + list_app = self.get_all_dropdown_options(self.application_dropdown) + for items in list_app[1:]: + assert items not in active or items not in deleted, "Not an Unknown Application option" + print("All Applications present are unknown") + + def generate_form_column_names(self, app, mod=None, forms=None): + column_list = [] + if mod == None and forms == None: + mod = list(UserData.reasign_modules_forms.keys()) + for m in mod: + for f in list(UserData.reasign_modules_forms[m]): + string = app+" > "+m+" > "+f + column_list.append(string) + elif mod !=None and forms == None: + for f in list(UserData.reasign_modules_forms[mod]): + string = app+" > "+mod+" > "+f + column_list.append(string) + else: + string = app + " > " + mod + " > " + forms + column_list.append(string) + print(column_list) + return column_list + + def form_column_verification(self, app, mod=None, form=None): + self.wait_to_click(self.sub_by_form_rep) + self.wait_for_element(self.apply_id) + assert self.sub_by_form_TITLE in self.driver.title, "This is not the Worker Activity page." + self.verify_user_lookup_table() + self.remove_default_users() + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.users_list_item.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.application_dropdown, app) + if mod == None and form == None: + column_list = self.generate_form_column_names(app) + self.select_by_text(self.application_dropdown, app) + elif mod != None and form == None: + column_list = self.generate_form_column_names(app, mod) + self.select_by_text(self.application_dropdown, app) + self.select_by_text(self.module_dropdown, mod) + else: + column_list = self.generate_form_column_names(app, mod, form) + self.select_by_text(self.application_dropdown, app) + self.select_by_text(self.module_dropdown, mod) + self.select_by_text(self.form_dropdown, form) + + self.select_by_text(self.filter_dates_by, UserData.filter_dates_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + text = self.get_attribute(self.date_input, "value") + print(text) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + self.verify_users_in_the_group() + for items in column_list: + assert self.is_present((By.XPATH, self.app_mod_form_column.format(items))), "Form Name Column not present: " + column_name + diff --git a/ElasticSearchTests/testPages/users/__init__.py b/ElasticSearchTests/testPages/users/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/users/group_page.py b/ElasticSearchTests/testPages/users/group_page.py new file mode 100644 index 000000000..1e0e6b7be --- /dev/null +++ b/ElasticSearchTests/testPages/users/group_page.py @@ -0,0 +1,106 @@ +import time + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string + +from selenium.webdriver.common.by import By + +""""Contains test page elements and functions related to the User's Groups module""" + + +class GroupPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + self.created_group = "group_" + fetch_random_string() + self.renamed_group = self.created_group + "_rename" + + self.created_group_path = "//a[contains(.,'{}')]"# (By.LINK_TEXT, self.created_group) + self.group_name = (By.ID, "id_group_name") + self.add_group_button = (By.XPATH, "//button[@type='submit' and @class='btn btn-primary']") + self.group_menu_xpath = (By.XPATH, "//a[@data-title='Groups']") + self.users_drop_down = (By.XPATH, "//span[@class='select2-selection select2-selection--multiple']") + self.select_user = "//li[text()='{}']" + self.update_button = (By.ID, "submit-id-submit") + self.group_created_success = (By.XPATH, "//h1[text()[contains(.,'Editing Group')]]") + self.edit_settings = (By.LINK_TEXT, "Edit Settings") + self.group_name_input = (By.ID, "group-name-input") + self.save_button = (By.XPATH, "//button[@type='submit' and text()='Save']") + self.success_alert = (By.ID, "save-alert") + self.remove_user = (By.XPATH, "//button[@title='Remove item']") + self.delete_group = (By.XPATH, "//a[@class='btn btn-danger pull-right']") + self.confirm_delete = (By.XPATH, "//button[@class='btn btn-danger disable-on-submit']") + self.delete_success_message = (By.XPATH, "//div[@class='alert alert-margin-top fade in html alert-success']") + # self.renamed_group_link = (By.LINK_TEXT, self.renamed_group) + + def click_group_menu(self): + self.wait_to_click(self.group_menu_xpath) + + def add_group(self): + self.click_group_menu() + self.wait_to_clear_and_send_keys(self.group_name, self.created_group) + self.wait_to_click(self.add_group_button) + assert self.is_visible_and_displayed(self.group_created_success), "Group not created successfully" + print("Group Added") + return self.created_group + + def add_user_to_group(self, username, group_name): + self.send_keys(self.users_drop_down, username) + self.wait_to_click((By.XPATH, self.select_user.format(username))) + self.wait_to_click(self.update_button) + print(self.driver.current_url) + group_id_value = self.driver.current_url.split("/")[-2] + time.sleep(2) + self.click_group_menu() + assert self.is_visible_and_displayed((By.XPATH, self.created_group_path.format(group_name))), "User could not be assigned to the group" + self.accept_pop_up() + print("User Added to Group") + return group_id_value + + def edit_existing_group(self, group_name): + self.click_group_menu() + time.sleep(2) + self.wait_to_click((By.XPATH, self.created_group_path.format(group_name))) + self.accept_pop_up() + self.wait_to_click(self.edit_settings) + renamed_group = group_name+"_rename" + self.wait_to_clear_and_send_keys(self.group_name_input, renamed_group) + self.click(self.save_button) + assert self.is_visible_and_displayed(self.success_alert), "Group could not be renamed" + print("Renamed a group") + return renamed_group + + def remove_user_from_group(self): + time.sleep(3) + self.js_click(self.remove_user) + self.js_click(self.update_button) + assert self.is_visible_and_displayed(self.success_alert), "User deletion from group not successful" + print("Removed added user from group") + time.sleep(2) + + def cleanup_group(self, renamed_group): + self.wait_to_click((By.XPATH, self.created_group.format(renamed_group))) + self.wait_to_click(self.delete_group) + self.wait_to_click(self.confirm_delete) + assert self.is_visible_and_displayed(self.delete_success_message), "Group deletion not successful" + print("Clean up added group") + + def delete_test_groups(self): + list_profile = self.driver.find_elements(By.XPATH,"//td//a[contains(text(),'group_')]") + print(list_profile) + try: + if len(list_profile) > 0: + for i in range(len(list_profile))[::-1]: + text = list_profile[i].text + print(text) + list_profile[i].click() + self.wait_to_click(self.delete_group) + self.wait_to_click(self.confirm_delete) + assert self.is_visible_and_displayed(self.delete_success_message), "Group deletion not successful" + time.sleep(2) + list_profile = self.driver.find_elements(By.XPATH,"//td//a[contains(text(),'group_')]") + else: + print("There are no test groups") + except: + print("There are no test groups") \ No newline at end of file diff --git a/ElasticSearchTests/testPages/users/mobile_workers_page.py b/ElasticSearchTests/testPages/users/mobile_workers_page.py new file mode 100644 index 000000000..e158c0be6 --- /dev/null +++ b/ElasticSearchTests/testPages/users/mobile_workers_page.py @@ -0,0 +1,622 @@ +import os +import random +import time + +import pandas as pd +from openpyxl import load_workbook + +from common_utilities.selenium.base_page import BasePage +from common_utilities.path_settings import PathSettings +from common_utilities.generate_random_string import fetch_random_string, fetch_phone_number +from HQSmokeTests.userInputs.user_inputs import UserData +from HQSmokeTests.testPages.users.org_structure_page import latest_download_file +from selenium.common.exceptions import TimeoutException, NoSuchElementException +from selenium.webdriver.common.by import By + +""""Contains test page elements and functions related to the User's Mobile Workers module""" + + +class MobileWorkerPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # self.username = random.choice(UserData.mobile_username_list) + # self.user = random.choice(UserData.mobile_user_list) + self.file_new_name = "mobile_workers_" + str(fetch_random_string()) + ".xlsx" + self.to_be_edited_file = os.path.abspath( + os.path.join(UserData.USER_INPUT_BASE_DIR, "test_data/mobile_workers.xlsx")) + self.renamed_file = os.path.abspath( + os.path.join(UserData.USER_INPUT_BASE_DIR, "test_data/" + self.file_new_name)) + self.username_cell = "A2" + + self.users_menu_id = (By.ID, "ProjectUsersTab") + self.login_as_username = "//h3/b[.='{}']" + self.profile_name_text = "test_profile_" + fetch_random_string() + self.phone_number = UserData.area_code + fetch_phone_number() + + self.username_link = "//a[./i[@class='fa fa-user']][strong[.='{}']]" + self.remove_choice_button = "(//input[contains(@data-bind,'value: slug')]//following::a[@class='btn btn-danger' and @data-toggle='modal'][1])[{}]//preceding::*[contains(@data-bind,'removeChoice')][1]" + self.confirm_user_field_delete = ( + By.XPATH, "(//a[.='Cancel']//following-sibling::button[@class='btn btn-danger'])[last()]") + self.delete_user_field = "(//input[contains(@data-bind,'value: slug')]//following::a[@class='btn btn-danger' and @data-toggle='modal'][1])[{}]" + self.delete_success_mw = (By.XPATH, "//div[@class='alert alert-margin-top fade in alert-success']") + self.confirm_delete_mw = (By.ID, "delete-user-icon") + self.enter_username = (By.XPATH, '//input[@data-bind="value: signOff, valueUpdate: \'textchange\'"]') + self.delete_mobile_worker = (By.XPATH, "//div[@class='alert alert-danger']//i[@class='fa fa-trash']") + self.actions_tab_link_text = (By.LINK_TEXT, "Actions") + # remove these two after locators page creation: redundant code + self.web_apps_menu_id = (By.ID, "CloudcareTab") + self.show_full_menu_id = (By.ID, "commcare-menu-toggle") + self.user_name_span = (By.CLASS_NAME, "user_username") + self.search_mw = (By.XPATH, "//div[@class='ko-search-box']//input[@type='text']") + self.search_button_mw = ( + By.XPATH, "//div[@class='ko-search-box']//button[@data-bind='click: clickAction, visible: !immediate']") + self.webapp_working_as = (By.XPATH, "//div[@class='restore-as-banner module-banner']/b") + self.webapp_login_confirmation = (By.ID, 'js-confirmation-confirm') + # self.webapp_login_with_username = (By.XPATH, self.login_as_usernames) + self.webapp_login = (By.XPATH, "(//div[@class='js-restore-as-item appicon appicon-restore-as'])") + self.confirm_reactivate_xpath_list = (By.XPATH, + "((//div[@class='modal-footer'])/button[@data-bind='click: function(user) { user.is_active(true); }'])") + self.reactivate_buttons_list = "//td[./a/strong[text()='{}']]/following-sibling::td/div[contains(@data-bind,'visible: !is_active()')]/button[contains(.,'Reactivate')]" + self.deactivate_button = "//td[./a/strong[text()='{}']]/following-sibling::td/div[contains(@data-bind,'visible: is_active()')]/button[contains(.,'Deactivate')]" + self.confirm_deactivate_xpath_list = ( + By.XPATH, "((//div[@class='modal-footer'])/button[@class='btn btn-danger'])") + self.deactivate_buttons_list = ( + By.XPATH, "(//td/div[@data-bind='visible: is_active()']/button[@class='btn btn-default'])") + self.show_deactivated_users_btn = ( + By.XPATH, + '//button[@data-bind="visible: !deactivatedOnly(), click: function() { deactivatedOnly(true); }"]') + self.usernames_xpath = (By.XPATH, "//td/a/strong[@data-bind='text: username']") + self.page_xpath = (By.XPATH, + "(//span[@data-bind='text: $data, visible: !$parent.showSpinner() || $data != $parent.currentPage()'])") + + self.users_menu_id = (By.ID, "ProjectUsersTab") + self.mobile_workers_menu_link_text = (By.LINK_TEXT, "Mobile Workers") + self.create_mobile_worker_id = (By.ID, "new-user-modal-trigger") + self.already_taken_error = (By.XPATH, "//span[contains(.,'is already taken')]") + self.mobile_worker_username_id = (By.ID, "id_username") + self.user_available_check = (By.XPATH, "//i[@class='fa fa-check' and @style='']") + self.mobile_worker_password_id = (By.ID, "id_new_password") + self.create_button_xpath = (By.XPATH, '//button[@type="submit"][contains(.,"Create")]') + self.error_message = ( + By.XPATH, "//span[@data-bind ='visible: $root.usernameAvailabilityStatus() !== $root.STATUS.NONE']") + self.cancel_button = ( + By.XPATH, "//button[@type='submit'][contains(.,'Create')]/preceding-sibling::button[text()='Cancel']") + self.new_user_created_xpath = (By.XPATH, + "//*[@class='success']//a[contains(@data-bind,'attr: {href: edit_url}, visible: user_id')]//following-sibling::strong") + self.NEW = (By.XPATH, "//span[@class='text-success']") + self.edit_user_field_xpath = (By.XPATH, "//a[contains(.,'Edit User Fields')]") + self.add_field_xpath = (By.XPATH, "//button[@data-bind='click: addField']") + self.user_property_xpath = (By.XPATH, "(//input[contains(@data-bind,'value: slug')])[last()]") + self.label_xpath = (By.XPATH, "(//input[contains(@data-bind,'value: label')])[last()]") + self.add_choice_button_xpath = (By.XPATH, "(//*[contains(@data-bind,'addChoice')])[last()]") + self.choices_button_xpath = (By.XPATH, "(//*[contains(@data-bind,\"validationMode('choice')\")][contains(.,'Choices')])[last()]") + self.choice_xpath = (By.XPATH, "(//input[contains(@data-bind,'value: value')])[last()]") + self.save_field_id = (By.ID, "save-custom-fields") + self.duplicate_field_error = (By.XPATH, "//div[contains(text(), 'was duplicated, key names must be unique')]") + self.user_field_success_msg = (By.XPATH, "//div[@class='alert alert-margin-top fade in alert-success']") + self.mobile_worker_on_left_panel = (By.XPATH, "//a[@data-title='Mobile Workers']") + self.next_page_button_xpath = (By.XPATH, "//a[contains(@data-bind,'click: nextPage')]") + self.additional_info_dropdown = ( + By.ID, "select2-id_data-field-user_field_" + fetch_random_string() + "-container") + self.select_value_dropdown = (By.XPATH, + "//select[@name = 'data-field-user_field_" + fetch_random_string() + "']/option[text()='user_field_" + fetch_random_string() + "']") + self.additional_info_select = ( + By.XPATH, "//select[@name = 'data-field-user_field_" + fetch_random_string() + "']") + self.additional_info_select2 = (By.XPATH, "//select[@name = 'data-field-field_" + fetch_random_string() + "']") + + self.additional_info_dropdown2 = ( + By.ID, "select2-id_data-field-" + "field_" + fetch_random_string() + "-container") + self.select_value_dropdown2 = (By.XPATH, + "//select[@name = 'data-field-field_" + fetch_random_string() + "']/option[text()='field_" + fetch_random_string() + "']") + + self.update_info_button = (By.XPATH, "//button[text()='Update Information']") + self.user_file_additional_info = ( + By.XPATH, "//label[@for='id_data-field-user_field_" + fetch_random_string() + "']") + self.user_file_additional_info2 = ( + By.XPATH, "//label[@for='id_data-field-field_" + fetch_random_string() + "']") + self.deactivate_btn_xpath = "//td/a/strong[text()='{}']/following::td[5]/div[@data-bind='visible: is_active()']/button" + self.confirm_deactivate = (By.XPATH, "(//button[@class='btn btn-danger'])[1]") + self.view_all_link_text = (By.LINK_TEXT, "View All") + self.search_user_web_apps = (By.XPATH, "//input[@placeholder='Filter workers']") + self.search_button_we_apps = (By.XPATH, "//div[@class='input-group-btn']") + + self.field_tab = (By.XPATH, "//a[@href='#tabs-fields']") + self.profile_tab = (By.XPATH, "//a[@href='#tabs-profiles']") + self.add_new_profile = (By.XPATH, "//button[@data-bind='click: addProfile']") + self.profile_name = (By.XPATH, "//tr[last()]//input[contains(@data-bind,'value: name')]") + self.profile_edit_button = (By.XPATH, "//tr[last()]//a[@class='btn btn-default enum-edit']") + self.profile_delete_button = ( + By.XPATH, "//tbody[@data-bind='foreach: profiles']//tr[last()]//td[last()]//i[@class='fa fa-times']") + self.add_profile_item = ( + By.XPATH, "//div[@class='modal fade hq-enum-modal in']//a[@data-enum-action='add']/i[@class='fa fa-plus']") + self.delete_profile_item = (By.XPATH, "//div[@class='modal fade hq-enum-modal in']//i[@class='fa fa-remove']") + self.profile_key = ( + By.XPATH, "//div[@class='modal fade hq-enum-modal in']//input[@class='form-control enum-key']") + self.profile_value = ( + By.XPATH, "//div[@class='modal fade hq-enum-modal in']//input[@class='form-control enum-value']") + self.done_button = (By.XPATH, "//div[@class='modal fade hq-enum-modal in']//button[@class='btn btn-primary']") + self.delete_field_choice = (By.XPATH, "//tbody[@data-bind='sortable: data_fields']//tr[last()]//td//*[contains(@data-bind,'removeChoice')]") + self.field_delete = ( + By.XPATH, "//tbody[@data-bind='sortable: data_fields']//tr[last()]//td[last()]//i[@class='fa fa-times']") + self.profile_combobox = ( + By.XPATH, "//span[@aria-labelledby='select2-id_data-field-commcare_profile-container']") + self.profile_selection = (By.XPATH, "//li[contains(text(),'" + self.profile_name_text + "')]") + self.profile_dropdown = (By.XPATH, "//select[@name='data-field-commcare_profile']") + self.phone_number_field = (By.XPATH, "//input[@name='phone_number']") + self.add_number_button = (By.XPATH, "//button[.='Add Number']") + self.registered_phone_number = (By.XPATH, "//label[contains(text(),'+" + self.phone_number + "')]") + + self.location_tab = (By.XPATH, "//a[@href='#commtrack-data']") + self.location_combobox = (By.XPATH, "//span[@class='select2-selection select2-selection--multiple']") + self.location_selection = (By.XPATH, "//li[contains(text(),'updated')]") + self.location_update_button = (By.XPATH, "//button[contains(text(),'Update Location Settings')]") + + # Download and Upload + self.download_worker_btn = (By.LINK_TEXT, "Download Mobile Workers") + self.download_users_btn = (By.LINK_TEXT, "Download Users") + self.bulk_upload_btn = (By.LINK_TEXT, "Bulk Upload") + self.choose_file = (By.XPATH, "//input[@id='id_bulk_upload_file']") + self.upload = (By.XPATH, "//button[@class='btn btn-primary disable-on-submit']") + self.successfully_uploaded = (By.XPATH, "//p[contains(text(),'Successfully uploaded')]") + self.import_complete = (By.XPATH, "//legend[text()='Bulk upload complete.']") + self.download_filter = (By.XPATH, "//button[contains(.,'Download')]") + self.error_403 = (By.XPATH, "//h1[text()='403 Forbidden']") + + self.bulk_user_delete_button = (By.XPATH, "//a[contains(@href,'users/commcare/delete')]") + self.successfully_deleted = (By.XPATH, "//text()[contains(.,'user(s) deleted')]") + self.no_user_found = (By.XPATH, "//text()[contains(.,'No users found')]") + + self.role_dropdown = (By.XPATH, "//select[@id='id_role']") + + def search_user(self, username): + self.wait_to_clear_and_send_keys(self.search_mw, username) + time.sleep(2) + self.wait_to_click(self.search_button_mw) + + def search_webapps_user(self, username): + self.wait_to_click(self.web_apps_menu_id) + self.wait_to_click(self.webapp_login) + time.sleep(1) + self.wait_for_element(self.search_user_web_apps, 20) + self.send_keys(self.search_user_web_apps, username) + self.wait_to_click(self.search_button_we_apps) + time.sleep(5) + + def mobile_worker_menu(self): + self.wait_to_click(self.mobile_workers_menu_link_text) + assert "Mobile Workers : Users :: - CommCare HQ" in self.driver.title, "Unable find the Users Menu." + + def create_mobile_worker(self): + try: + self.wait_to_click(self.create_mobile_worker_id) + time.sleep(1) + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Couldn't find create mobile worker button. ") + + def mobile_worker_enter_username(self, username): + self.send_keys(self.mobile_worker_username_id, username) + self.wait_for_element(self.user_available_check, 40) + return username + + def mobile_worker_enter_password(self, password): + self.send_keys(self.mobile_worker_password_id, password) + + def click_create(self, username): + self.wait_to_click(self.create_button_xpath) + time.sleep(5) + self.is_present_and_displayed(self.NEW) + new_user_created = self.get_text(self.new_user_created_xpath) + print("Username is : " + new_user_created) + assert username == new_user_created, "Could find the new mobile worker created" + print("Mobile Worker Created") + + def check_for_group_in_downloaded_file(self, newest_file, group_id_value): + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + time.sleep(5) + data = pd.read_excel(path, sheet_name='groups') + df = pd.DataFrame(data, columns=['id']) + assert group_id_value in df['id'].values, "Group is not present" + + def edit_profile_in_downloaded_file(self, newest_file, user): + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + time.sleep(5) + data = pd.read_excel(path, sheet_name='users') + df = pd.DataFrame(data) + df = df.drop(columns="phone-number 1") + df = df.query("username == '"+user+"'") + print(df) + df.loc[(df['username'] == user), 'user_profile'] = UserData.p1p2_profile + df.to_excel(path, sheet_name='users', index=False) + + def remove_role_in_downloaded_file(self, newest_file, user): + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + time.sleep(5) + data = pd.read_excel(path, sheet_name='users') + df = pd.DataFrame(data) + df = df.query("username == '"+user+"'") + df = df.drop(columns="role") + df.to_excel(path, sheet_name='users',index=False) + + def edit_user_field(self): + self.wait_to_click(self.edit_user_field_xpath) + + def add_field(self): + self.wait_to_click(self.add_field_xpath) + + def add_user_property(self, user_pro): + self.clear(self.user_property_xpath) + self.send_keys(self.user_property_xpath, user_pro) + + def add_label(self, label): + self.clear(self.label_xpath) + self.send_keys(self.label_xpath, label) + + def add_choice(self, choice): + if self.is_present(self.choices_button_xpath): + self.wait_to_click(self.choices_button_xpath) + self.scroll_to_element(self.add_choice_button_xpath) + self.wait_for_element(self.add_choice_button_xpath) + self.wait_to_click(self.add_choice_button_xpath) + self.clear(self.choice_xpath) + self.send_keys(self.choice_xpath, choice) + + def save_field(self): + if self.is_enabled(self.save_field_id): + self.wait_to_click(self.save_field_id) + time.sleep(5) + assert self.is_present(self.user_field_success_msg) or self.is_present( + self.duplicate_field_error), "Unable to save userfield/profile." + print("User Field/Profile Added or is already present") + else: + print("Save Button is not enabled") + + def select_mobile_worker_created(self, username): + time.sleep(2) + self.wait_to_click(self.mobile_worker_on_left_panel) + time.sleep(2) + self.search_user(username) + time.sleep(3) + if not self.is_present((By.XPATH, self.username_link.format(username))): + self.click(self.show_deactivated_users_btn) + self.click((By.XPATH, self.username_link.format(username))) + self.wait_for_element(self.user_name_span) + print("Mobile Worker page opened.") + + def enter_value_for_created_user_field(self): + self.select_by_text(self.additional_info_select, "user_field_" + fetch_random_string()) + assert self.is_displayed(self.user_file_additional_info), "Unable to assign user field to user." + + def update_information(self): + time.sleep(2) + self.wait_to_click(self.update_info_button) + time.sleep(4) + assert self.is_displayed(self.user_field_success_msg), "Unable to update user." + print("User Field Visible and Added for User") + time.sleep(2) + + def deactivate_user(self, username): + try: + self.search_user(username) + time.sleep(1) + self.wait_for_element((By.XPATH, self.username_link.format(username)), 50) + self.wait_to_click(self.deactivate_buttons_list) + self.wait_for_element(self.confirm_deactivate_xpath_list) + self.wait_to_click(self.confirm_deactivate_xpath_list) + time.sleep(5) + assert self.is_present_and_displayed((By.XPATH, self.reactivate_buttons_list.format(username)), 20) + print("Deactivation successful") + return "Success" + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Deactivation Unsuccessful.") + return "Not Success" + + def verify_deactivation_via_login(self, username, text): + if text == "Success": + self.search_webapps_user(username) + assert self.is_present_and_displayed((By.XPATH, self.login_as_username.format(username)), + 10) == False, "Deactivated mobile worker still visible" + self.click(self.show_full_menu_id) + else: + assert False + + def reactivate_user(self, username): + try: + time.sleep(1) + self.mobile_worker_menu() + self.wait_to_click(self.show_deactivated_users_btn) + self.search_user(username) + time.sleep(1) + self.wait_for_element((By.XPATH, self.username_link.format(username)), 50) + self.wait_to_click((By.XPATH, self.reactivate_buttons_list.format(username))) + self.wait_for_element(self.confirm_reactivate_xpath_list) + self.wait_to_click(self.confirm_reactivate_xpath_list) + time.sleep(5) + assert self.is_present_and_displayed((By.XPATH, self.deactivate_button.format(username)), 20) + print("Reactivation successful") + return "Success" + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Reactivation unsuccessful.") + return "Not Success" + + def verify_reactivation_via_login(self, username, text): + if text == "Success": + self.search_webapps_user(username) + assert self.is_present_and_displayed((By.XPATH, self.login_as_username.format(username))), "user is not activated" + self.wait_to_click((By.XPATH, self.login_as_username.format(username))) + self.wait_to_click(self.webapp_login_confirmation) + self.click(self.show_full_menu_id) + login_username = self.get_text(self.webapp_working_as) + assert login_username == username, "Reactivated user is not visible." + print("Working as " + username + " : Reactivation successful!") + time.sleep(1) + else: + assert False + + def cleanup_mobile_worker(self): + try: + self.wait_to_click(self.actions_tab_link_text) + self.wait_to_click(self.delete_mobile_worker) + self.wait_to_clear_and_send_keys(self.enter_username, self.username + "@" + self.get_domain() + + ".commcarehq.org") + self.wait_to_click(self.confirm_delete_mw) + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Could not delete the mobile worker") + self.is_present_and_displayed(self.delete_success_mw), "Mobile User Deletion Unsuccessful" + + def cleanup_user_field(self): + time.sleep(1) + self.wait_to_click(self.delete_user_field) + self.wait_to_click(self.confirm_user_field_delete) + self.wait_to_click(self.done_button) + + def delete_test_user_field(self): + time.sleep(3) + list_profile = self.driver.find_elements(By.XPATH, "//input[contains(@data-bind,'value: slug')]") + if len(list_profile) > 0: + for i in range(len(list_profile))[::-1]: + time.sleep(3) + text = list_profile[i].get_attribute("value") + if "field_" in text: + self.wait_to_click((By.XPATH, self.remove_choice_button.format(str(i + 1)))) + self.wait_to_click((By.XPATH, self.delete_user_field.format(str(i+1)))) + # self.driver.find_element(By.XPATH, + # "(//input[contains(@data-bind,'value: slug')]//following::a[@class='btn btn-danger' and @data-toggle='modal'][1])[" + str( + # i + 1) + "]").click() + self.wait_to_click(self.confirm_user_field_delete) + time.sleep(2) + list_profile = self.driver.find_elements(By.XPATH, "//input[contains(@data-bind,'value: slug')]") + else: + print("Its not a test user field") + self.save_field() + else: + print("No test user field present in the list") + + def download_mobile_worker(self): + time.sleep(1) + self.mobile_worker_menu() + self.wait_to_click(self.download_worker_btn) + self.wait_to_click(self.download_filter) + time.sleep(5) + try: + self.wait_and_sleep_to_click(self.download_users_btn, 150) + time.sleep(5) + except TimeoutException: + print("TIMEOUT ERROR: Still preparing for download..Celery might be down..") + assert False + # verify_downloaded_workers + newest_file = latest_download_file() + self.assert_downloaded_file(newest_file, "_users_"), "Download Not Completed!" + print("File download successful") + + return newest_file + + def upload_mobile_worker(self): + self.mobile_worker_menu() + try: + self.click(self.bulk_upload_btn) + newest_file = latest_download_file() + file_that_was_downloaded = PathSettings.DOWNLOAD_PATH / newest_file + time.sleep(5) + self.send_keys(self.choose_file, str(file_that_was_downloaded)) + self.wait_and_sleep_to_click(self.upload) + self.wait_for_element(self.successfully_uploaded, 150) + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Could not upload file") + assert self.is_present_and_displayed(self.import_complete), "Upload Not Completed! Taking Longer to process.." + print("File uploaded successfully") + + def click_profile(self): + self.wait_to_click(self.profile_tab) + + def click_fields(self): + self.click(self.field_tab) + + def add_profile(self, user_field): + self.wait_to_click(self.add_new_profile) + self.wait_to_clear_and_send_keys(self.profile_name, self.profile_name_text) + time.sleep(2) + self.wait_to_click(self.profile_edit_button) + time.sleep(2) + self.js_click(self.add_profile_item) + self.send_keys(self.profile_key, user_field) + self.send_keys(self.profile_value, user_field) + self.wait_to_click(self.done_button) + + def select_profile(self): + self.wait_to_click(self.profile_combobox) + time.sleep(1) + self.wait_to_click(self.profile_selection) + + def add_phone_number(self): + self.wait_to_clear_and_send_keys(self.phone_number_field, self.phone_number) + time.sleep(1) + self.js_click(self.add_number_button) + time.sleep(3) + assert self.is_present_and_displayed(self.registered_phone_number), "Phone Number not registered." + print("Phone Number registered successfully") + + def select_location(self): + self.wait_to_click(self.location_tab) + self.wait_to_click(self.location_combobox) + self.wait_to_click(self.location_selection) + self.wait_to_click(self.location_update_button) + + def remove_user_field(self): + self.wait_to_click(self.delete_field_choice) + self.wait_to_click(self.field_delete) + self.wait_to_click(self.confirm_user_field_delete) + + def remove_profile(self): + self.wait_to_click(self.profile_edit_button) + self.wait_to_click(self.delete_profile_item) + self.wait_to_click(self.done_button) + time.sleep(2) + self.wait_to_click(self.profile_delete_button) + self.wait_to_click(self.confirm_user_field_delete) + + def delete_profile(self): + list_profile = self.driver.find_elements(By.XPATH, "//input[contains(@data-bind,'value: name')]") + if len(list_profile) > 0: + for i in range(len(list_profile))[::-1]: + text = list_profile[i].get_attribute("value") + if "test_profile" in text: + self.driver.find_element(By.XPATH, + "(//input[contains(@data-bind,'value: name')]//following::a[@class='btn btn-danger' and @data-toggle='modal'][1])[" + str( + i + 1) + "]").click() + self.wait_to_click(self.confirm_user_field_delete) + time.sleep(2) + list_profile = self.driver.find_elements(By.XPATH, "//input[contains(@data-bind,'value: name')]") + else: + print("Its not a test profile") + self.save_field() + else: + print("No test profile present in the list") + + def create_new_mobile_worker(self, user): + self.create_mobile_worker() + user = self.mobile_worker_enter_username(user) + self.mobile_worker_enter_password(fetch_random_string()) + self.wait_to_click(self.create_button_xpath) + time.sleep(4) + self.is_present_and_displayed(self.NEW) + new_user_created = self.get_text(self.new_user_created_xpath) + print("Username is : " + new_user_created) + assert user == new_user_created, "Could find the new mobile worker created" + print("Mobile Worker Created") + + + def create_new_user_fields(self, userfield): + self.edit_user_field() + self.add_field() + self.add_user_property(userfield) + self.add_label(userfield) + self.add_choice(userfield) + self.save_field() + + def select_user_and_update_fields(self, user, field): + time.sleep(2) + self.select_mobile_worker_created(user) + self.select_by_text(self.additional_info_select2, field) + assert self.is_displayed(self.user_file_additional_info2), "Unable to assign user field to user." + + def select_and_delete_mobile_worker(self, user): + time.sleep(2) + self.wait_to_click(self.mobile_worker_on_left_panel) + time.sleep(2) + self.wait_to_clear_and_send_keys(self.search_mw, user) + time.sleep(2) + self.wait_to_click(self.search_button_mw) + time.sleep(3) + self.click((By.LINK_TEXT, user)) + try: + self.wait_to_click(self.actions_tab_link_text) + self.wait_to_click(self.delete_mobile_worker) + self.wait_to_clear_and_send_keys(self.enter_username, user + "@" + self.get_domain() + + ".commcarehq.org") + self.wait_to_click(self.confirm_delete_mw) + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Could not delete the mobile worker") + self.is_present_and_displayed(self.delete_success_mw), "Mobile User Deletion Unsuccessful" + + def delete_bulk_users(self): + latest = PathSettings.DOWNLOAD_PATH / self.download_mobile_worker() + print(latest) + new_data = pd.read_excel(latest, sheet_name='users') + print('Original Row count: ', new_data.shape) + # filter the test users + new_data = new_data[new_data['username'].str.startswith(("user_","username_"))] + print('Filtered Row count: ', new_data.shape) + new_data.drop(new_data.columns.difference(['username']), axis=1, inplace=True) + print("New Data", new_data) + print("New data values", new_data.values) + if new_data.empty == False: + writer = pd.ExcelWriter(latest, engine='openpyxl') + # write data to the excel sheet + new_data.to_excel(writer, sheet_name='users', index=False) + # close file + writer.close() + self.bulk_delete_mobile_worker_upload(latest) + else: + print("No test users to delete") + + def bulk_delete_mobile_worker_upload(self, file_path): + self.mobile_worker_menu() + try: + self.click(self.bulk_user_delete_button) + time.sleep(5) + self.send_keys(self.choose_file, str(file_path)) + self.wait_and_sleep_to_click(self.upload) + time.sleep(2) + self.wait_for_element(self.successfully_deleted, 70) + # if self.is_present_and_displayed(self.successfully_deleted, 50): + print("User(s) deleted successfully") + # elif self.is_present_and_displayed(self.no_user_found, 50): + # print("No test user present") + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Could not upload file") + + + def bulk_upload_mobile_worker(self): + self.wait_to_click(self.users_menu_id) + self.mobile_worker_menu() + try: + self.click(self.bulk_upload_btn) + self.edit_username_in_excel(self.to_be_edited_file, self.username_cell, self.renamed_file) + time.sleep(2) + self.wait_to_clear_and_send_keys(self.choose_file, self.renamed_file) + self.wait_and_sleep_to_click(self.upload) + self.wait_for_element(self.successfully_uploaded, 150) + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Could not upload file") + assert self.is_present_and_displayed(self.import_complete), "Upload Not Completed! Taking Longer to process.." + print("File uploaded successfully") + + + def edit_username_in_excel(self, edited_file, cell, renamed_file, sheet_name='users'): + workbook = load_workbook(filename=edited_file) + sheet = workbook.active + sheet[cell] = "user_p1p2_"+fetch_random_string() + sheet.title = sheet_name + workbook.save(filename=renamed_file) + + def update_role_for_mobile_worker(self, role): + self.wait_for_element(self.role_dropdown) + self.select_by_text(self.role_dropdown, role) + self.update_information() + + def verify_role_for_mobile_worker(self, role): + self.wait_for_element(self.role_dropdown) + text = self.get_selected_text(self.role_dropdown) + print(text) + assert text == role, "Role is not the same as set before upload" + + def verify_profile_change(self, profile): + self.wait_for_element(self.profile_dropdown) + text = self.get_selected_text(self.profile_dropdown) + print(text) + assert text == profile, "Profile is not the same as set before upload" \ No newline at end of file diff --git a/ElasticSearchTests/testPages/users/org_structure_page.py b/ElasticSearchTests/testPages/users/org_structure_page.py new file mode 100644 index 000000000..26ba72693 --- /dev/null +++ b/ElasticSearchTests/testPages/users/org_structure_page.py @@ -0,0 +1,331 @@ +import os +import time +from datetime import date + +from HQSmokeTests.testPages.home.home_page import HomePage +from common_utilities.selenium.base_page import BasePage +from common_utilities.path_settings import PathSettings +from common_utilities.generate_random_string import fetch_random_string +from selenium.common.exceptions import TimeoutException, StaleElementReferenceException +from selenium.webdriver.common.by import By + +""""Contains test page elements and functions related to the User's Organization structure module""" + + +def latest_download_file(type=".xlsx"): + cwd = os.getcwd() + try: + os.chdir(PathSettings.DOWNLOAD_PATH) + all_specific_files = filter(lambda x: x.endswith(type), os.listdir(os.getcwd())) + files = sorted(all_specific_files, key=os.path.getctime) + if files[-1].endswith(".log"): + newest = sorted(files, key=os.path.getctime)[-2] + elif files[-1].endswith(".xlsx"): + newest = sorted(files, key=os.path.getctime)[-1] + else: + newest = max(files, key=os.path.getctime) + print("File downloaded: " + newest) + return newest + finally: + print("Restoring the path...") + os.chdir(cwd) + print("Current directory is-", os.getcwd()) + + +class OrganisationStructurePage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + self.new_location_name = "location_" + fetch_random_string() + self.loc_field_name = "location_field_" + str(fetch_random_string()) + self.loc_level_name = "loc_level_" + fetch_random_string() + + self.org_menu_link_text = (By.LINK_TEXT, "Organization Structure") + self.add_loc_btn_xpath = ( + By.XPATH, "//span[@data-bind='text: new_child_caption' and text()='New location at top level']") + self.loc_name_xpath = (By.XPATH, "//input[@type='text']") + self.create_loc_xpath = (By.XPATH, "//button[@type='submit']") + self.loc_saved_success_msg = (By.XPATH, "//div[@class ='alert alert-margin-top fade in alert-success']") + self.error_1_id = (By.ID, "error_1_id_name") + self.edit_this_loc = (By.XPATH, "(//span[contains(text(),'updated_on:')])[1]") + self.edit_loc_button_xpath = (By.XPATH, + "(//span[contains(text(),'updated_on:')])[1]//preceding::a[@data-bind='attr: { href: loc_edit_url(uuid()) }'][1]") + self.loc_name_input_id = (By.ID, "id_name") + self.update_loc_xpath = (By.XPATH, "(//button[@type='submit'])[1]") + self.location_created_xpath = (By.XPATH, "//span[text()='" + self.new_location_name + "']") + self.renamed_location = (By.XPATH, "//span[text()='updated_on:" + str(date.today()) + "']") + self.edit_loc_field_btn_xpath = (By.XPATH, "//a[@data-action='Edit Location Fields']") + self.add_field_btn_xpath = (By.XPATH, "//button[contains(@data-bind,'click: addField')]") + self.loc_property_xpath = (By.XPATH, "(//input[contains(@data-bind,'value: slug')])[last()]") + self.loc_label_xpath = (By.XPATH, "(//input[contains(@data-bind,'value: label')])[last()]") + self.choice_selection = (By.XPATH, "(//div[contains(@data-bind, \"validationMode('choice')\")])[last()]") + self.choices_button_xpath = (By.XPATH, "(//*[contains(text(), 'Choices')])[last()]") + self.add_choice_btn_xpath = (By.XPATH, "(//button[contains(@data-bind,'click: addChoice')])[last()]") + self.choice_xpath = (By.XPATH, "(//input[contains(@data-bind,'value: value')])[last()]") + self.save_btn_id = (By.ID, "save-custom-fields") + self.success_msg_xpath = (By.XPATH, "//div[@class='alert alert-margin-top fade in alert-success']") + self.additional_info_drop_down = ( + By.XPATH, "//*[@id='select2-id_data-field-" + self.loc_field_name + "-container']") + self.select_value_drop_down = (By.XPATH, "//li[text()='" + self.loc_field_name + "']") + self.duplicate_msg_xpath = (By.XPATH, "//div[@class='alert alert-danger']") + self.org_level_menu_link_text = (By.LINK_TEXT, "Organization Levels") + self.new_org_level_btn_xpath = (By.XPATH, "//button[@data-bind='click: new_loctype']") + self.org_level_value_xpath = (By.XPATH, "(//input[@data-bind='value: name'])[last()]") + self.save_btn_xpath = (By.XPATH, "//button[@type='submit' and @class='btn btn-default pull-right btn-primary']") + self.save_btn_delete = (By.XPATH, "//button[@class='btn btn-default pull-right']") + self.download_loc_btn = (By.LINK_TEXT, "Download Organization Structure") + self.upload_loc_btn = (By.LINK_TEXT, "Bulk Upload") + self.upload = (By.XPATH, "//button[@class='btn btn-primary disable-on-submit']") + self.import_complete = (By.XPATH, "//legend[text()='Import complete.']") + self.download_filter = (By.XPATH, "//button[@data-bind='html: buttonHTML']") + self.bulk_upload_id = (By.ID, "id_bulk_upload_file") + self.test_locations = (By.XPATH, "//span[@class='loc_name']") + self.test_location = (By.XPATH, "(//span[contains(text(),'Test Location [DO NOT DELETE!!!')])[1]") + self.archive_buttton = (By.XPATH, + "//div[.//span[.='Test Location [DO NOT DELETE!!!]']]/preceding-sibling::div/button[normalize-space()= 'Archive']") + self.archive_button_popup = (By.XPATH, "//button[@data-bind='click: archive_fn']") + self.archive_success_message = (By.XPATH, "//span[@data-bind='html: message']") + self.show_arhcived_locations_button = (By.XPATH, "//a[@class='btn btn-default pull-right'][contains(.,'Archived Locations')]") + self.show_active_locations = (By.XPATH, "//a[@class='btn btn-default pull-right'][contains(.,'Active Locations')]") + self.unarchive_button = (By.XPATH, + '''//div[.//span[.='Test Location [DO NOT DELETE!!!]']]/preceding-sibling::div/button[normalize-space()= "Unarchive"]''') + + # cleanup + self.delete_location_created = ( + By.XPATH, "//span[text ()='" + self.new_location_name + "']//preceding::button[@class='btn btn-danger'][1]") + self.delete_confirm = (By.XPATH, '//input[@data-bind ="value: signOff, valueUpdate: \'input\'"]') + self.delete_confirm_button = ( + By.XPATH, "//button[@data-bind ='click: delete_fn, css: {disabled: !(signOff() == count)}']") + self.delete_loc_field = (By.XPATH, "(//a[@class='btn btn-danger'])[last()]") + self.delete_org_level = (By.XPATH, "(//a[.='Cancel']//following-sibling::button[@class='btn btn-danger'])[last()]") + self.delete_success = (By.XPATH, "//div[@class='alert fade in message-alert alert-success']") + + def organisation_menu_open(self): + self.wait_to_click(self.org_menu_link_text) + print(self.driver.title) + assert "Organization Structure : Locations :: - CommCare HQ" in self.driver.title + + def create_location(self): + self.wait_to_click(self.add_loc_btn_xpath) + self.wait_to_clear_and_send_keys(self.loc_name_xpath, self.new_location_name) + self.click(self.create_loc_xpath) + assert self.is_present_and_displayed(self.loc_saved_success_msg), "Location not created!" + self.wait_to_click(self.org_menu_link_text) + self.driver.refresh() + try: + assert self.is_present_and_displayed(self.location_created_xpath), "Location not created!" + except StaleElementReferenceException: + assert self.is_present_and_displayed(self.location_created_xpath), "Location not created!" + + def edit_location(self): + try: + self.wait_to_click(self.org_menu_link_text) + self.click(self.edit_loc_button_xpath) + self.wait_to_clear_and_send_keys(self.loc_name_input_id, "updated_on:" + str(date.today())) + self.click(self.update_loc_xpath) + time.sleep(2) + assert self.is_visible_and_displayed(self.loc_saved_success_msg), "Location editing not successful!" + self.click(self.org_menu_link_text) + self.driver.refresh() + assert self.is_visible_and_displayed(self.renamed_location), "Location editing not successful!" + except StaleElementReferenceException: + print(StaleElementReferenceException) + + def edit_location_fields(self): + self.click(self.org_menu_link_text) + self.wait_to_click(self.edit_loc_field_btn_xpath) + self.wait_to_click(self.add_field_btn_xpath) + self.wait_to_clear_and_send_keys(self.loc_property_xpath, self.loc_field_name) + self.wait_to_clear_and_send_keys(self.loc_label_xpath, self.loc_field_name) + if self.is_present(self.choices_button_xpath): + self.wait_to_click(self.choices_button_xpath) + self.click(self.add_choice_btn_xpath) + self.wait_to_clear_and_send_keys(self.choice_xpath, self.loc_field_name) + self.click(self.save_btn_id) + assert self.is_displayed(self.success_msg_xpath), "Location field edit not successful!" + self.driver.refresh() + + def selection_location_field_for_location_created(self): + try: + self.click(self.org_menu_link_text) + self.wait_to_click(self.edit_loc_button_xpath) + self.wait_to_click(self.additional_info_drop_down) + self.click(self.select_value_drop_down) + self.click(self.update_loc_xpath) + assert self.is_present_and_displayed(self.success_msg_xpath), "Location field not assigned!" + except StaleElementReferenceException: + print(StaleElementReferenceException) + + def create_org_level(self): + self.click(self.org_level_menu_link_text) + self.wait_to_click(self.new_org_level_btn_xpath) + self.wait_to_clear_and_send_keys(self.org_level_value_xpath, self.loc_level_name) + self.wait_to_click(self.save_btn_xpath) + + def download_locations(self): + self.click(self.org_menu_link_text) + self.click(self.download_loc_btn) + self.wait_to_click(self.download_filter) + try: + self.wait_and_sleep_to_click(self.download_loc_btn) + time.sleep(5) + except TimeoutException: + print("Still preparing for download..") + assert False + # verify_downloaded_location + newest_file = latest_download_file() + self.assert_downloaded_file(newest_file, "_locations"), "Download not completed!" + print("File download successful") + + def upload_locations(self): + self.click(self.org_menu_link_text) + self.click(self.upload_loc_btn) + newest_file = latest_download_file() + file_that_was_downloaded = PathSettings.DOWNLOAD_PATH / newest_file + self.send_keys(self.bulk_upload_id, str(file_that_was_downloaded)) + time.sleep(2) + self.wait_to_click(self.upload) + self.is_present_and_displayed(self.import_complete), "Upload not completed!" + print("File uploaded successfully") + + def cleanup_location(self): + # Delete User Field + self.wait_to_click(self.org_menu_link_text) + self.wait_to_click(self.edit_loc_field_btn_xpath) + self.wait_to_click(self.delete_loc_field) + self.wait_to_click(self.delete_org_level) + self.wait_to_click(self.save_btn_id) + print("Location field deleted successfully") + self.delete_test_location() + self.delete_test_org_level() + + def delete_test_org_level(self): + # # Delete Org Level + self.js_click(self.org_level_menu_link_text) + time.sleep(3) + list_org_level = self.driver.find_elements(By.XPATH, "//input[@class='loctype_name form-control']") + print(len(list_org_level)) + if len(list_org_level) > 0: + for i in range(len(list_org_level))[::-1]: + text = list_org_level[i].get_attribute("value") + print(text) + if "loc_level_" in text: + self.driver.find_element(By.XPATH, + "(//td[.//input[@class='loctype_name form-control']]/following-sibling::td//button[@class='btn btn-danger'])[" + str( + i + 1) + "]").click() + self.wait_to_click(self.save_btn_delete) + self.driver.refresh() + time.sleep(3) + list_org_level = self.driver.find_elements(By.XPATH, "//input[@class='loctype_name form-control']") + else: + print("Not a text location") + else: + print("No location present") + print("Org level deleted successfully") + + def delete_test_location(self): + # Delete Location + self.wait_to_click(self.org_menu_link_text) + time.sleep(2) + list_location = self.driver.find_elements(By.XPATH, "//span[@class='loc_name' and contains(.,'location_')]") + print(list_location) + print(len(list_location)) + if len(list_location) > 0: + for i in range(len(list_location))[::-1]: + text = list_location[i].text + print(text) + time.sleep(2) + self.driver.find_element(By.XPATH, + "(//div[./span[@class='loc_name' and contains(.,'location_')]]//preceding-sibling::div/button[@class='btn btn-danger'])[" + str( + i + 1) + "]").click() + self.wait_to_clear_and_send_keys(self.delete_confirm, "1") + self.click(self.delete_confirm_button) + assert self.is_present_and_displayed(self.delete_success), "Location Not Deleted!" + print("Location deleted successfully") + self.driver.refresh() + time.sleep(3) + list_location = self.driver.find_elements(By.XPATH, + "//span[@class='loc_name' and contains(.,'location_')]") + else: + print("No test locations present") + + def archive_location(self): + self.wait_to_click(self.org_menu_link_text) + active_loc = self.is_present_and_displayed(self.test_location, 10) + if not active_loc: + self.wait_to_click(self.show_arhcived_locations_button) + self.wait_to_click(self.unarchive_button) + self.assert_archived_location() + else: + self.assert_archived_location() + + def assert_archived_location(self): + self.wait_to_click(self.org_menu_link_text) + time.sleep(5) + self.wait_for_element(self.test_location, 40) + # self.is_present_and_displayed(self.test_location, 10) + active_loc = self.find_elements(self.test_locations) + loc_list = [] + print(active_loc) + if len(active_loc) > 0: + for i in range(len(active_loc)): + print(active_loc[i].text) + loc_list.append(active_loc[i].text) + print("Active: ", loc_list) + assert "Test Location [DO NOT DELETE!!!]" in loc_list, "Location not Unarchived successfully" + # active_loc = self.get_text(self.test_location) + self.wait_to_click(self.archive_buttton) + self.wait_to_click(self.archive_button_popup) + self.is_present_and_displayed(self.archive_success_message, 10) + self.driver.refresh() + check_archived_loc = self.is_present_and_displayed(self.test_location, 10) + assert not check_archived_loc, "Location is still Active" + self.wait_to_click(self.show_arhcived_locations_button) + time.sleep(5) + archived_loc = self.find_elements(self.test_locations) + archive_list = [] + print(archived_loc) + if len(archived_loc) > 0: + for i in range(len(archived_loc)): + print(archived_loc[i].text) + archive_list.append(archived_loc[i].text) + print("Archived: ", archive_list) + assert "Test Location [DO NOT DELETE!!!]" in archive_list, "Location is not Archived" + + def unarchive_location(self, settings): + self.wait_for_element(self.test_location, 40) + archived_loc = self.is_present_and_displayed(self.test_location, 10) + if not archived_loc: + self.wait_to_click(self.show_active_locations) + self.wait_to_click(self.archive_buttton) + self.wait_to_click(self.archive_button_popup) + self.assert_unarchived_location(settings) + else: + self.assert_unarchived_location(settings) + + def assert_unarchived_location(self, settings): + if self.is_present(self.show_arhcived_locations_button): + self.wait_to_click(self.show_arhcived_locations_button) + time.sleep(5) + archived_loc = self.get_text(self.test_location) + self.wait_to_click(self.unarchive_button) + self.driver.refresh() + time.sleep(3) + check_unarchived_loc = self.is_present_and_displayed(self.test_location, 10) + assert not check_unarchived_loc, "Location is still Unarchived" + self.wait_to_click(self.show_active_locations) + home = HomePage(self.driver, settings) + home.users_menu() + self.wait_to_click(self.org_menu_link_text) + time.sleep(5) + unarchived_loc = self.find_elements(self.test_locations) + loc_list = [] + print(unarchived_loc) + if len(unarchived_loc) > 0: + for i in range(len(unarchived_loc)): + print(unarchived_loc[i].text) + loc_list.append(unarchived_loc[i].text) + print("unarchived: ",loc_list) + assert "Test Location [DO NOT DELETE!!!]" in loc_list, "Location not Unarchived successfully" + diff --git a/ElasticSearchTests/testPages/users/roles_permissions_page.py b/ElasticSearchTests/testPages/users/roles_permissions_page.py new file mode 100644 index 000000000..ba3a9543f --- /dev/null +++ b/ElasticSearchTests/testPages/users/roles_permissions_page.py @@ -0,0 +1,145 @@ +import time + +from selenium.common import ElementNotInteractableException +from selenium.webdriver.common.actions.interaction import KEY + +from HQSmokeTests.testPages.home.home_page import HomePage +from HQSmokeTests.testPages.users.web_user_page import WebUsersPage +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string + +from HQSmokeTests.userInputs.user_inputs import UserData +from selenium.webdriver.common.by import By + +""""Contains test page elements and functions related to the User's Roles and Permissions module""" + + +class RolesPermissionPage(BasePage): + + def __init__(self, driver, settings): + super().__init__(driver) + self.settings = settings + + self.role_name_created = "role_" + fetch_random_string() + self.role_non_admin_created = "role_non_" + fetch_random_string() + self.role_rename_created = "role_rename_" + fetch_random_string() + self.roles_menu = (By.XPATH, "//a[@data-title='Roles & Permissions']") + self.add_new_role = ( + By.XPATH, "//button[@data-bind='click: function () {$root.setRoleBeingEdited($root.defaultRole)}']") + self.role_name = (By.ID, "role-name") + self.edit_web_user_checkbox = (By.XPATH, "//input[@id='edit-web-users-checkbox']") + self.save_button = (By.XPATH, "//button[@class='btn btn-primary disable-on-submit']") + self.role_created = (By.XPATH, "//span[text()='" + str(self.role_name_created) + "']") + self.edit_created_role = (By.XPATH, "//th[.//span[.='" + str( + self.role_name_created) + "']]/following-sibling::td//*[@class='fa fa-edit']") + self.delete_role = (By.XPATH, "//th[.//span[.='" + str( + self.role_name_created) + "']]/following-sibling::td//i[@class='fa fa-trash']") + self.edit_mobile_worker_checkbox = (By.XPATH, "//input[@id='edit-commcare-users-checkbox']") + self.report_for_p1p2 = (By.XPATH, "//div[contains(@data-bind,'reportPermission')]//label[./span[.='"+UserData.report_for_p1p2+"']]") + self.role_renamed = (By.XPATH, "//span[text()='" + str(self.role_rename_created) + "']") + self.role_non_admin = (By.XPATH, "//span[text()='" + str(self.role_non_admin_created) + "']") + self.confirm_role_delete = (By.XPATH, "//div[@class='btn btn-danger']") + self.full_org_access_checkbox = (By.XPATH, "//label[contains(.,'Full Organization Access')]//following-sibling::div//input") + self.access_all_reports_checkbox = (By.XPATH, "//input[@id='access-all-reports-checkbox']") + + + def roles_menu_click(self): + self.wait_to_click(self.roles_menu) + assert "Roles & Permissions : Users :: - CommCare HQ" in self.driver.title + + def add_role(self): + self.wait_to_click(self.add_new_role) + self.wait_to_clear_and_send_keys(self.role_name, self.role_name_created) + time.sleep(1) + self.click(self.edit_web_user_checkbox) + self.scroll_to_element(self.save_button) + time.sleep(0.5) + self.click(self.save_button) + time.sleep(2) + assert self.is_present_and_displayed(self.role_created), "Role not added successfully!" + + def edit_role(self): + self.wait_to_click(self.edit_created_role) + self.wait_to_clear_and_send_keys(self.role_name, self.role_rename_created) + time.sleep(1) + self.click(self.edit_mobile_worker_checkbox) + self.scroll_to_element(self.save_button) + time.sleep(0.5) + self.click(self.save_button) + time.sleep(2) + assert self.is_present_and_displayed(self.role_renamed), "Role not edited successfully!" + time.sleep(1) + + def cleanup_role(self): + self.wait_to_click(self.delete_role) + self.wait_to_click(self.confirm_role_delete) + + def delete_test_roles(self): + list_profile = self.driver.find_elements(By.XPATH, "//th[.//span[contains(text(),'role_')]]") + print(list_profile) + try: + if len(list_profile) > 0: + for i in range(len(list_profile))[::-1]: + text = list_profile[i].text + print(text) + self.driver.find_element(By.XPATH, + "(//th[.//span[contains(text(),'role_')]]//following-sibling::td//button[@class='btn btn-danger'])[" + str( + i + 1) + "]").click() + self.wait_to_click(self.confirm_role_delete) + time.sleep(2) + list_profile = self.driver.find_elements(By.XPATH, "//th[.//span[contains(text(),'role_')]]") + else: + print("There are no test roles") + except ElementNotInteractableException: + menu = HomePage(self.driver, self.settings) + webuser = WebUsersPage(self.driver) + menu.users_menu() + webuser.edit_user_permission("Admin") + menu.users_menu() + self.roles_menu_click() + list_profile = self.driver.find_elements(By.XPATH, "//th[.//span[contains(text(),'role_')]]") + print(list_profile) + if len(list_profile) > 0: + for i in range(len(list_profile))[::-1]: + text = list_profile[i].text + print(text) + self.driver.find_element(By.XPATH, + "(//th[.//span[contains(text(),'role_')]]//following-sibling::td//button[@class='btn btn-danger'])[" + str( + i + 1) + "]").click() + self.wait_to_click(self.confirm_role_delete) + time.sleep(2) + list_profile = self.driver.find_elements(By.XPATH, "//th[.//span[contains(text(),'role_')]]") + else: + print("There are no test roles") + + + + def add_non_admin_role(self): + self.wait_to_click(self.add_new_role) + self.wait_to_clear_and_send_keys(self.role_name, self.role_non_admin_created) + time.sleep(1) + self.click(self.edit_mobile_worker_checkbox) + self.scroll_to_element(self.access_all_reports_checkbox) + is_checked = self.get_attribute(self.access_all_reports_checkbox, 'checked') + print("All report access checked ", is_checked) + if is_checked == True: + self.wait_to_click(self.access_all_reports_checkbox) + assert self.get_attribute(self.access_all_reports_checkbox, 'checked') == False, "Access is checked" + else: + assert True + self.scroll_to_element(self.report_for_p1p2) + time.sleep(0.5) + self.wait_to_click(self.report_for_p1p2) + is_checked = self.get_attribute(self.full_org_access_checkbox, 'checked') + print("All report access checked ", is_checked) + if is_checked == True: + self.wait_to_click(self.full_org_access_checkbox) + assert self.get_attribute(self.full_org_access_checkbox, 'checked') == False, "Access is checked" + else: + assert True + self.scroll_to_element(self.save_button) + time.sleep(0.5) + self.click(self.save_button) + time.sleep(2) + assert self.is_present_and_displayed(self.role_non_admin), "Role not added successfully!" + return self.role_non_admin_created \ No newline at end of file diff --git a/ElasticSearchTests/testPages/users/web_user_page.py b/ElasticSearchTests/testPages/users/web_user_page.py new file mode 100644 index 000000000..314a517a5 --- /dev/null +++ b/ElasticSearchTests/testPages/users/web_user_page.py @@ -0,0 +1,205 @@ +import time +import re +from datetime import date +from datetime import datetime + +from selenium.common.exceptions import TimeoutException +from selenium.webdriver.common.by import By +from selenium.webdriver.support.select import Select + +from common_utilities.selenium.base_page import BasePage +from common_utilities.path_settings import PathSettings +from HQSmokeTests.userInputs.user_inputs import UserData +from HQSmokeTests.testPages.users.org_structure_page import latest_download_file +from selenium.common.exceptions import NoSuchElementException + +""""Contains test page elements and functions related to the User's Web Users module""" + + +class WebUsersPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + self.driver = driver + self.users_menu_id = (By.ID, "ProjectUsersTab") + self.web_users_menu = (By.LINK_TEXT, "Web Users") + self.invite_web_user_button = (By.XPATH, "//i[@class='fa fa-plus']") + self.email_input = (By.XPATH, "//input[@class='emailinput form-control']") + self.select_project_role_id = (By.XPATH, "//select[@id='id_role']") + self.send_invite = (By.XPATH, "//button[contains(text(),'Send Invite')]") + self.delete_confirm_invitation = (By.XPATH, "//button[@data-bind = 'click: $root.removeInvitation']") + self.delete_confirm_webuser = (By.XPATH, + "(//td[.//text()[contains(.,'" + UserData.yahoo_user_name + "')]]/following-sibling::td//i[@class='fa fa-trash'])[last()]") + self.delete_success = (By.XPATH, "//div[@class='alert alert-margin-top fade in html alert-success']") + self.verify_user = (By.XPATH, + "//td[.//text()[contains(.,'" + UserData.yahoo_user_name + "')]]/following-sibling::td[.//text()[contains(.,'Delivered')]]") + self.remove_user_invite = (By.XPATH, + "//td[.//text()[contains(.,'" + UserData.yahoo_user_name + "')]]/following-sibling::td//i[@class='fa fa-trash']") + self.login_username = (By.ID, "login-username") + self.next_button = (By.ID, "login-signin") + self.login_password = (By.NAME, "password") + self.signin_button = (By.ID, "login-signin") + self.mail_icon = (By.XPATH, "//div[@class= 'icon mail']") + self.latest_mail = (By.XPATH, "(//span[contains(@title,'Invitation from')])[1]") + self.invitation_received_date = (By.XPATH, '//div[@data-test-id="message-date"]') + self.accept_invitation = (By.XPATH, "//*[contains(text(), 'Accept Invitation')]") + self.accept_invitation_hq = (By.XPATH, "//button[contains(text(), 'Accept Invitation')]") + self.full_name = (By.NAME, "full_name") + self.create_password = (By.NAME, "password") + self.check_checkbox = (By.ID, "id_eula_confirmed") + self.create_button = (By.XPATH, "//button[@type='submit']") + self.settings = (By.XPATH, "//a[@data-action='Click Gear Icon']") + self.sign_out = (By.XPATH, "//a[contains(@data-label,'Sign Out')]") + self.creation_success = (By.XPATH, "//div[@class='alert alert-margin-top fade in alert-success']") + self.password_textbox = (By.ID, 'id_auth-password') + self.submit_button_xpath = (By.XPATH, '(//button[@type="submit"])[last()]') + self.existing_error = (By.ID, 'error_1_id_email') + self.download_worker_btn = (By.LINK_TEXT, "Download Web Users") + self.download_filter = (By.XPATH, "//button[@class='btn btn btn-primary']") + self.download_users_btn = (By.LINK_TEXT, "Download Users") + self.bulk_upload_btn = (By.ID, "bulk_upload") + self.choose_file = (By.XPATH, "//input[@id='id_bulk_upload_file']") + self.upload = (By.XPATH, "//button[@class='btn btn-primary disable-on-submit']") + self.import_complete = (By.XPATH, "//legend[text()='Bulk upload complete.']") + self.search_user = (By.XPATH, "//input[contains(@placeholder,'Search Users')]") + self.search_user_btn = (By.XPATH, "//form[.//input[contains(@placeholder,'Search Users')]]//button/i[@class='fa fa-search']") + self.user_link = (By.LINK_TEXT,UserData.p1p2_user) + self.update_role_btn = (By.XPATH, "//button[.='Update Role']") + self.location_field = (By.XPATH, "//textarea[@class='select2-search__field']") + self.remove_location = (By.XPATH, "//button[@aria-label='Remove item']") + self.location_value = (By.XPATH, "//li[contains(@class,'select2-results__option')][.='Test Location [DO NOT DELETE!!!]']") + self.update_location_btn = (By.XPATH, "//button[.='Update Location Settings']") + + + def invite_new_web_user(self, role): + self.wait_to_click(self.web_users_menu) + self.wait_to_click(self.invite_web_user_button) + self.wait_to_clear_and_send_keys(self.email_input, UserData.yahoo_user_name) + self.select_by_value(self.select_project_role_id, role) + self.wait_to_click(self.send_invite) + if self.is_visible_and_displayed(self.existing_error): + self.delete_invite() + self.wait_to_click(self.invite_web_user_button) + self.wait_to_clear_and_send_keys(self.email_input, UserData.yahoo_user_name) + self.select_by_value(self.select_project_role_id, role) + self.wait_to_click(self.send_invite) + + def assert_invitation_sent(self): + time.sleep(10) + self.wait_to_click(self.users_menu_id) + self.wait_to_click(self.web_users_menu) + assert self.is_visible_and_displayed(self.verify_user), "Unable to find delivered invite." + print("Web user invitation sent successfully") + + def assert_invitation_received(self, mail_url, mail_username, mail_password): + self.wait_to_click(self.settings) + self.wait_to_click(self.sign_out) + print("Signed out successfully") + self.driver.get(mail_url) + self.wait_to_clear_and_send_keys(self.login_username, mail_username) + self.wait_and_sleep_to_click(self.next_button) + self.wait_to_clear_and_send_keys(self.login_password, mail_password) + self.wait_and_sleep_to_click(self.signin_button) + self.wait_to_click(self.mail_icon) + self.click(self.latest_mail) + self.verify_invitation_received() + + def verify_invitation_received(self): + received_date_on_yahoo = self.get_text(self.invitation_received_date) + stripped_strings = re.findall(r'\w+', received_date_on_yahoo) + unwanted = [0, 2] + for ele in unwanted: + del stripped_strings[ele] + stripped_strings.insert(2, str(date.today().year)) + invitation_received_datetime = datetime.strptime(" ".join(stripped_strings), '%d %b %Y %I %M %p') + current_time = datetime.now() + time_difference = round((current_time - invitation_received_datetime).total_seconds()) + print(time_difference) + assert time_difference in range(0, 200), "Unable to find invite" + + def accept_webuser_invite(self, mail_usename, mail_password): + self.wait_to_click(self.accept_invitation) + self.switch_to_next_tab() + try: + self.wait_to_clear_and_send_keys(self.full_name, mail_usename) + self.wait_to_clear_and_send_keys(self.create_password, mail_password) + self.wait_to_click(self.check_checkbox) + self.wait_to_click(self.create_button) + except TimeoutException: + self.send_keys(self.password_textbox, mail_password) + self.wait_to_click(self.submit_button_xpath) + self.wait_to_click(self.accept_invitation_hq) + assert "CommCare HQ" in self.driver.title, "Invitation Acceptance Failed" + self.wait_to_click(self.settings) + self.wait_to_click(self.sign_out) + print("Signed out successfully") + + def delete_invite(self): + self.wait_to_click(self.users_menu_id) + self.wait_to_click(self.web_users_menu) + self.wait_to_click(self.remove_user_invite) + try: + time.sleep(2) + self.js_click(self.delete_confirm_invitation) + except TimeoutException: + time.sleep(2) + self.js_click(self.delete_confirm_webuser) + print("Invitation deleted") + + def download_web_users(self): + time.sleep(1) + self.wait_to_click(self.users_menu_id) + self.wait_to_click(self.web_users_menu) + self.wait_to_click(self.download_worker_btn) + self.wait_to_click(self.download_filter) + try: + self.wait_and_sleep_to_click(self.download_users_btn) + time.sleep(5) + except TimeoutException: + print("TIMEOUT ERROR: Still preparing for download..Celery might be down..") + assert False + # verify_downloaded_workers + newest_file = latest_download_file() + self.assert_downloaded_file(newest_file, "_users_"), "Download Not Completed!" + print("File download successful") + + def upload_web_users(self): + self.wait_to_click(self.users_menu_id) + self.wait_to_click(self.web_users_menu) + try: + self.click(self.bulk_upload_btn) + newest_file = latest_download_file() + file_that_was_downloaded = PathSettings.DOWNLOAD_PATH / newest_file + time.sleep(5) + self.send_keys(self.choose_file, str(file_that_was_downloaded)) + self.wait_and_sleep_to_click(self.upload) + except (TimeoutException, NoSuchElementException): + print("TIMEOUT ERROR: Could not upload file") + assert self.is_present_and_displayed(self.import_complete), "Upload Not Completed! Taking Longer to process.." + print("File uploaded successfully") + + def edit_user_permission(self, rolename): + self.wait_to_click(self.web_users_menu) + self.wait_for_element(self.search_user) + self.wait_to_clear_and_send_keys(self.search_user, UserData.p1p2_user) + time.sleep(1) + self.wait_to_click(self.search_user_btn) + time.sleep(2) + self.wait_for_element(self.user_link) + self.wait_to_click(self.user_link) + self.wait_for_element(self.select_project_role_id) + self.select_by_text(self.select_project_role_id, rolename) + self.wait_to_click(self.update_role_btn) + time.sleep(2) + self.scroll_to_element(self.location_field) + if self.is_present(self.remove_location): + self.wait_to_click(self.remove_location) + time.sleep(2) + self.wait_to_click(self.location_field) + self.send_keys(self.location_field, "Test Location") + self.wait_to_click(self.location_value) + self.wait_to_click(self.update_location_btn) + time.sleep(2) + + diff --git a/ElasticSearchTests/testPages/users/webapps_permission_page.py b/ElasticSearchTests/testPages/users/webapps_permission_page.py new file mode 100644 index 000000000..9a5b2aeb5 --- /dev/null +++ b/ElasticSearchTests/testPages/users/webapps_permission_page.py @@ -0,0 +1,34 @@ +from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver.common.by import By + +from common_utilities.selenium.base_page import BasePage + +""""Contains test page elements and functions related to the User's Webapps Permissions module""" + + +class WebAppPermissionPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + self.web_app_permissions_menu = (By.LINK_TEXT, "Web Apps Permissions") + self.first_radio_button = (By.XPATH, "//input[@name='ko_unique_1']") + self.second_radio_button = (By.XPATH, "//input[@name='ko_unique_2']") + self.save_button = (By.XPATH, "//div[@class='btn btn-primary']") + self.after_save = (By.XPATH, "//div[@class='btn btn-primary disabled']") + self.error_403 = (By.XPATH, "//h1[text()='403 Forbidden']") + + def webapp_permission_option_toggle(self): + try: + self.click(self.web_app_permissions_menu) + except NoSuchElementException: + if self.is_displayed(self.error_403): + self.driver.back() + self.driver.implicitly_wait(2) + if self.is_selected(self.first_radio_button): + self.click(self.second_radio_button) + else: + self.click(self.first_radio_button) + self.click(self.save_button) + assert self.is_visible_and_displayed(self.after_save) + print("Webapps permissions toggled") diff --git a/ElasticSearchTests/testPages/worker_activity/__init__.py b/ElasticSearchTests/testPages/worker_activity/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/testPages/worker_activity/worker_activity_page.py b/ElasticSearchTests/testPages/worker_activity/worker_activity_page.py new file mode 100644 index 000000000..db83ccdb1 --- /dev/null +++ b/ElasticSearchTests/testPages/worker_activity/worker_activity_page.py @@ -0,0 +1,822 @@ +import html +import os +import time + +import dateutil.relativedelta +import pandas as pd + +from datetime import datetime, timedelta, date +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from HQSmokeTests.testPages.data.export_data_page import latest_download_file +from common_utilities.path_settings import PathSettings + +from common_utilities.selenium.base_page import BasePage +from common_utilities.generate_random_string import fetch_random_string +from ElasticSearchTests.userInputs.user_inputs import UserData + +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as ec + +""""Contains test page elements and functions related to the Reports module""" + + +class WorkerActivityPage(BasePage): + + def __init__(self, driver): + super().__init__(driver) + + # Mobile Worker Reports + self.reports_menu_id = (By.ID, "ProjectReportsTab") + self.worker_activity_rep = (By.LINK_TEXT, "Worker Activity") + self.WORKER_ACTIVITY_TITLE = "Worker Activity - CommCare HQ" + + # Report Elements + self.apply_id = (By.ID, "apply-filters") + self.report_content_id = (By.ID, "report-content") + self.homepage = (By.XPATH, ".//a[@href='/homepage/']") + + self.form_activity_results = (By.XPATH, "//table[@id='report_table_worker_activity']/tbody/tr") + self.form_activity_results_cells = (By.XPATH, "//table[@id='report_table_worker_activity']/tbody/tr/td") + self.users_field = (By.XPATH, "(//textarea[@class='select2-search__field'])[1]") + self.remove_buttons = (By.XPATH, "//ul//button") + self.user_remove_btn = (By.XPATH, "(//button[@class='select2-selection__choice__remove'])[last()]") + self.user_from_list = "//li[contains(.,'{}')]" + self.export_to_excel = (By.XPATH, "//a[@id='export-report-excel']") + self.export_success = (By.XPATH, + "//span[.='Your requested Excel report will be sent to the email address defined in your account settings.']") + self.user_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_worker_activity']/div[contains(.,'User')])[1]") + self.group_column = ( + By.XPATH, "(//thead/tr/th[@aria-controls='report_table_worker_activity']/div[contains(.,'Group')])[1]") + self.view_by_dropdown = (By.XPATH, "//select[@id='report_filter_view_by']") + self.case_type_textarea = ( + By.XPATH, "//label[contains(.,'Case Type')]//following-sibling::div//textarea[@role='searchbox']") + self.case_type_list_item = "//ul[@role='listbox']/li[contains(.,'{}')]" + self.case_type_list = (By.XPATH, "//ul[contains(@id,'select2-case_type')]/li") + self.case_type_list_empty = ( + By.XPATH, "//ul[contains(@id,'select2-case_type')]/li[.='The results could not be loaded.']") + self.date_input = (By.XPATH, "//input[@id='filter_range']") + self.date_range_type = "//li[@data-range-key='{}']" + self.column_names = "(//thead/tr/th[@aria-controls='report_table_worker_activity']/div[@data-title='{}'])[1]" + self.column_group_names = "(//thead/tr/th//strong[.='{}'])[1]" + self.user_names_column_list = (By.XPATH, "//table[@id='report_table_worker_activity']//tbody//td[1]") + self.last_submission_column_list = (By.XPATH, "//table[@id='report_table_worker_activity']//tbody//td[4]") + self.result_table = (By.XPATH, "(//div[@id='report-content']//table//tbody//td[1])[1]") + self.results_rows = (By.XPATH, "//tbody/tr") + self.result_rows_names = "//tbody/tr/td[1][contains(.,'{}')]" + self.hide_filters_options = (By.XPATH, "//a[.='Hide Filter Options']") + self.show_filters_options = (By.XPATH, "//a[.='Show Filter Options']") + self.user_sort = ( + By.XPATH, "(//text()[contains(.,'User')]//preceding-sibling::i[@class='icon-white fa dt-sort-icon'])[1]") + self.active_cases_column_list = (By.XPATH, "//table[@id='report_table_worker_activity']//tbody//td[7]") + self.total_cases_shared_column_list = (By.XPATH, "//table[@id='report_table_worker_activity']//tbody//td[8]") + + # Pagination + self.page_list_dropdown = (By.XPATH, "//select[@name='report_table_worker_activity_length']") + self.table_info = (By.XPATH, "//div[@id='report_table_worker_activity_info']") + self.prev_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='prev']/a") + self.next_page_button = (By.XPATH, "//ul[@class='pagination']/li[@class='next']/a") + self.prev_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='prev disabled']/a") + self.next_page_button_disabled = (By.XPATH, "//ul[@class='pagination']/li[@class='next disabled']/a") + self.page_button = "//ul[@class='pagination']/li/a[.='{}']" + self.pagination_list = (By.XPATH, "//ul[@class='pagination']/li/a") + + # Custom date selector + self.from_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='monthselect']") + self.from_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//select[@class='yearselect']") + self.from_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar left']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + + self.to_month = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='monthselect']") + self.to_year = (By.XPATH, + "//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//select[@class='yearselect']") + self.to_date = "(//div[contains(@class,'show-calendar')]//div[@class='drp-calendar right']//descendant::tbody//td[.='{}'][not(contains(@class,'off available'))])[1]" + self.apply_date = ( + By.XPATH, "//div[contains(@class,'show-calendar')]//div[@class='drp-buttons']//button[.='Apply']") + + # Save Report and Favorites + self.favorite_button = (By.XPATH, "//button[contains(.,'Favorites')]") + self.empty_fav_list = (By.XPATH, '//a[.="You don\'t have any favorites"]') + self.saved_fav = "//a[contains(.,'{}')][contains(@data-bind,'text: name')]" + self.save_config_button = (By.XPATH, "//button[@data-bind='click: setConfigBeingEdited']") + self.name_field = (By.XPATH, "//input[@data-bind='value: name']") + self.description_field = (By.XPATH, "//textarea[@data-bind='value: description']") + self.date_range_field_select = (By.XPATH, "//select[@data-bind='value: date_range']") + self.save_report_button = (By.XPATH, "//div[@class='btn btn-primary'][.='Save']") + self.cancel_report_button = (By.XPATH, "//div/a[.='Cancel']") + self.saved_reports_menu_link = (By.LINK_TEXT, 'My Saved Reports') + self.saved_report_created = "//a[text()='{}']" + self.delete_saved = "(//a[text()='{}']//following::button[@class='btn btn-danger add-spinner-on-click'])[1]" + + # Case Type Verify + self.case_created_column = (By.XPATH, "//table[@id='report_table_worker_activity']//tbody//td[5]//a") + self.case_created_title = (By.XPATH, "//table[@id='report_table_worker_activity']//tbody//td[5]//span") + self.case_list_table = (By.XPATH, "//table[@id='report_table_case_list']/tbody/tr/td[1]") + self.case_list_table_title = (By.XPATH, "//h2[@class='panel-title'][contains(.,'Case List')]") + self.case_list_table_info = (By.XPATH, "//div[@id='report_table_case_list_info']") + self.case_list_page_dropdown = (By.XPATH, "//select[@name='report_table_case_list_length']") + + # Email report + self.email_report_btn = (By.XPATH, "//a[@id='email-report']") + self.email_subject_field = (By.XPATH, "//input[@id='id_subject']") + self.email_form_cancel_btn = (By.XPATH, "//input[@id='button-id-close']") + self.send_email_btn = (By.XPATH, "//input[@id='submit-id-submit_btn']") + self.email_success_message = (By.XPATH, "//*[.='Report successfully emailed']") + + def hide_filters(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.hide_filters_options) + self.click(self.hide_filters_options) + time.sleep(2) + assert not self.is_visible_and_displayed(self.users_field, 10), "User field is still present" + assert not self.is_visible_and_displayed(self.view_by_dropdown, 10), "View By field is still present" + assert not self.is_visible_and_displayed(self.date_input, 10), "Date Range field is still present" + assert not self.is_visible_and_displayed(self.case_type_textarea, 10), "Case Type field is still present" + assert self.is_present(self.show_filters_options), "Show Filters Options is not present" + print("All filters are hidden!") + + def show_filters(self): + self.wait_for_element(self.show_filters_options) + self.click(self.show_filters_options) + time.sleep(2) + assert self.is_present(self.users_field), "User field is not present" + assert self.is_present(self.view_by_dropdown), "View By field is not present" + assert self.is_present(self.date_input), "Date Range field is not present" + assert self.is_present(self.case_type_textarea), "Case Type field is not present" + assert self.is_present(self.hide_filters_options), "Show Filters Options is not present" + print("All filters are shown!") + + def worker_activity_report_no_case_type(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.user_column), "User Column not present" + for item in UserData.wa_column_group_names: + assert self.is_visible_and_displayed((By.XPATH, self.column_group_names.format(item))), "Column not present" + print(item, " is present!") + + for item in UserData.wa_column_names: + assert self.is_visible_and_displayed( + (By.XPATH, self.column_names.format(item))), " Column " + item + " not present" + print(item, " is present!") + + def verify_users_in_the_group(self): + list = self.find_elements(self.results_rows) + if len(list) > 0: + for item in UserData.automation_group_users: + assert self.is_present((By.XPATH, self.result_rows_names.format( + item))), "Group user " + item + " is not present in results." + print("Group User " + item + " is present in results.") + + def worker_activity_report_group_case_type(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[1]) + self.wait_to_click(self.case_type_textarea) + time.sleep(2) + assert not self.is_visible_and_displayed(self.case_type_list_empty, 10), "Case Type List is not empty" + list = self.find_elements(self.case_type_list) + print(len(list)) + assert int(len(list)) >= 1 + print("A Look up for Case type is successfully loaded") + self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.case_pregnancy))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + assert self.is_present(self.group_column), "Group Column not present" + assert self.is_present((By.XPATH, self.result_rows_names.format( + UserData.user_group))), "Group user " + UserData.user_group + " is not present in results." + print("Group User " + UserData.user_group + " is present in results.") + self.click((By.LINK_TEXT, UserData.user_group)) + self.switch_to_next_tab() + time.sleep(5) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.wait_for_element(self.result_table, 60) + assert UserData.view_by[0] == self.get_selected_text(self.view_by_dropdown), "Values do not match " + \ + UserData.view_by[ + 0] + " and " + self.get_selected_text( + self.view_by_dropdown) + print("Users option for the selected group is selected") + self.scroll_to_bottom() + self.verify_users_in_the_group() + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def worker_activity_pagination_list(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[1]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + pages = self.find_elements(self.pagination_list) + pages_count = len(pages) - 2 + print("Total Pages: ", pages_count) + first_page = pages[1].text + last_page = pages[-2].text + if pages_count > 1: + assert self.is_present(self.prev_page_button_disabled), "Previous button is not disabled." + print("Previous button disabled correctly") + print("Clicking on page " + last_page) + self.wait_to_click((By.XPATH, self.page_button.format(last_page))) + time.sleep(15) + assert self.is_present(self.next_page_button_disabled), "Next button is not disabled." + print("Next button disabled correctly") + time.sleep(5) + print("Clicking on page " + first_page) + self.wait_to_click((By.XPATH, self.page_button.format(first_page))) + time.sleep(15) + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + self.wait_to_click(self.next_page_button) + time.sleep(5) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + print(list1_names, list2_names) + assert list1_names != list2_names, "Both Pages have same values" + print("Next button functioning correctly.") + self.wait_to_click(self.prev_page_button) + time.sleep(5) + list3 = self.find_elements(self.user_names_column_list) + list3_names = list() + for item in list3: + list3_names.append(item.text) + print(list1_names, list2_names, list3_names) + assert list1_names == list3_names and list2_names != list3_names, "Page contains same data as the previous" + print("Prev button functioning correctly.") + else: + print("Not enough users are present.") + assert self.is_present(self.prev_page_button_disabled) + assert self.is_present(self.next_page_button_disabled) + print("Both Previous and Next Page buttons are disabled correctly.") + + def verify_pagination_dropdown(self): + info = self.get_text(self.table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + + for item in UserData.pagination: + self.select_by_value(self.page_list_dropdown, item) + time.sleep(10) + list = self.find_elements(self.user_names_column_list) + print(len(list)) + if int(info[-2]) < int(item): + assert int(len(list)) == int(info[-2]), "List does not have all records." + print("Records displayed correctly for " + item) + elif int(info[-2]) >= int(item): + assert int(len(list)) == int(item), "List does not have all records." + print("Records displayed correctly for " + item) + else: + print("No records to display") + + def verify_sorted_list(self): + list1 = self.find_elements(self.user_names_column_list) + list1_names = list() + for item in list1: + list1_names.append(item.text) + sorted_list = sorted(list1_names) + assert list1_names == sorted_list, "List is not sorted" + print("List is in ascending order") + self.wait_to_click(self.user_sort) + time.sleep(15) + list2 = self.find_elements(self.user_names_column_list) + list2_names = list() + for item in list2: + list2_names.append(item.text) + rev_list = sorted(list1_names, reverse=True) + assert list2_names == rev_list, "List is not sorted" + print("List is in descending order") + + def value_date_range_7_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + week_ago = presentday - timedelta(7) + return str(week_ago.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), week_ago.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_30_days(self): + presentday = datetime.now() # or presentday = datetime.today() + # Get Today minus 7 days date + pastday = presentday - timedelta(30) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def value_date_range_last_month(self): + last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) + start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) + print(start_day_of_prev_month, last_day_of_prev_month) + return str(start_day_of_prev_month.strftime('%Y-%m-%d') + " to " + last_day_of_prev_month.strftime( + '%Y-%m-%d')), start_day_of_prev_month.strftime( + '%Y-%m-%d'), last_day_of_prev_month.strftime('%Y-%m-%d') + + def worker_activity_search(self, date_range=UserData.date_range[0]): + date_string = start_date = end_date = '' + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.case_type_textarea) + time.sleep(2) + assert not self.is_visible_and_displayed(self.case_type_list_empty, 10), "Case Type List is not empty" + case_list = self.find_elements(self.case_type_list) + print(len(case_list)) + assert int(len(case_list)) >= 1 + print("A Look up for Case type is successfully loaded") + self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.case_reassign))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(date_range))) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + if date_range == UserData.date_range[0]: + date_string, start_date, end_date = self.value_date_range_7_days() + elif date_range == UserData.date_range[1]: + date_string, start_date, end_date = self.value_date_range_last_month() + elif date_range == UserData.date_range[2]: + date_string, start_date, end_date = self.value_date_range_30_days() + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + date_list = self.find_elements(self.last_submission_column_list) + date_values = list() + for item in date_list: + date_values.append(item.text) + print(date_values) + for item in date_values: + if item == "None": + print("No Report for this user within the provided date range") + else: + self.date_validator(item, start_date, end_date) + print("Dates are with range for " + date_range) + + def date_validator(self, date_value, start_date, end_date): + dt = parse(date_value) + st = parse(start_date) + et = parse(end_date) + print(dt, st, et) + if st <= dt <= et: + assert True, "Date outside date range" + print("within range") + else: + print("not within range") + assert False + + def worker_activity_search_custom_date(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.case_type_textarea) + time.sleep(2) + assert not self.is_visible_and_displayed(self.case_type_list_empty, 10), "Case Type List is not empty" + case_list = self.find_elements(self.case_type_list) + print(len(case_list)) + assert int(len(case_list)) >= 1 + print("A Look up for Case type is successfully loaded") + self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.case_reassign))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[3]))) + date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 5) + self.select_date_from_picker(start_date, end_date) + time.sleep(2) + text = self.get_attribute(self.date_input, "value") + print(text) + assert text == date_string + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_element(self.result_table) + time.sleep(5) + date_list = self.find_elements(self.last_submission_column_list) + date_values = list() + for item in date_list: + date_values.append(item.text) + print(date_values) + for item in date_values: + if item == "None": + print("No Report for this user within the provided date range") + else: + self.date_validator(item, start_date, end_date) + print("Dates are with range for " + UserData.date_range[3]) + + def get_custom_dates_past(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + pastday = presentday - relativedelta(days=days, months=months, years=years) + return str(pastday.strftime('%Y-%m-%d') + " to " + presentday.strftime('%Y-%m-%d')), pastday.strftime( + '%Y-%m-%d'), presentday.strftime('%Y-%m-%d') + + def get_custom_dates_future(self, days, months, years): + presentday = datetime.now() # or presentday = datetime.today() + futureday = presentday + relativedelta(days=days, months=months, years=years) + return str(presentday.strftime('%Y-%m-%d') + " to " + futureday.strftime('%Y-%m-%d')), presentday.strftime( + '%Y-%m-%d'), futureday.strftime('%Y-%m-%d') + + def select_date_from_picker(self, start_date, end_date): + start_date = parse(start_date) + start_day = str(start_date.day) + start_month = str(start_date.month - 1) + start_year = str(start_date.year) + end_date = parse(end_date) + end_day = str(end_date.day) + end_month = str(end_date.month - 1) + end_year = str(end_date.year) + self.wait_for_element(self.from_month) + self.select_by_value(self.from_year, start_year) + time.sleep(2) + self.select_by_value(self.from_month, start_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.from_date.format(start_day))) + time.sleep(2) + self.wait_for_element(self.to_month) + self.select_by_value(self.to_year, end_year) + time.sleep(2) + self.select_by_value(self.to_month, end_month) + time.sleep(2) + self.wait_to_click((By.XPATH, self.to_date.format(end_day))) + time.sleep(2) + self.wait_to_click(self.apply_date) + + def worker_activity_save_report(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.case_type_textarea) + time.sleep(2) + assert not self.is_visible_and_displayed(self.case_type_list_empty, 10), "Case Type List is not empty" + case_list = self.find_elements(self.case_type_list) + print(len(case_list)) + assert int(len(case_list)) >= 1 + print("A Look up for Case type is successfully loaded") + self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.case_reassign))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.verify_case_type_data() + time.sleep(10) + self.verify_favorite_empty() + self.save_report_donot_save() + report = self.save_report() + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + self.verify_favorite_created(report) + self.delete_saved_report(report) + self.wait_to_click(self.worker_activity_rep) + self.verify_favorite_empty() + + def verify_favorite_empty(self): + self.wait_to_click(self.favorite_button) + assert self.is_visible_and_displayed(self.empty_fav_list), "Favorites Already Present" + print("No Favorites yet.") + + def verify_favorite_created(self, report): + self.wait_to_click(self.favorite_button) + assert not self.is_visible_and_displayed(self.empty_fav_list, 10), "Favorites Already Present" + assert self.is_visible_and_displayed((By.XPATH, self.saved_fav.format(report))), "Favorite Not Present" + print("Favorites added.") + self.wait_to_click((By.XPATH, self.saved_fav.format(report))) + + def delete_saved_report(self, report): + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 120) + print("Report Present!") + self.click((By.XPATH, self.delete_saved.format(report))) + print("Deleted Saved Report") + time.sleep(5) + self.driver.refresh() + assert not self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report)), 20) + print("Deleted Report Successfully") + + def save_report_donot_save(self): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + report_name = "Saved Worker Activity Report " + fetch_random_string() + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.cancel_report_button) + time.sleep(2) + assert not self.is_visible_and_displayed(self.name_field, 10), "Save Report Form not closed" + print("Save Report Form is closed") + + def save_report(self): + self.wait_for_element(self.save_config_button) + self.wait_to_click(self.save_config_button) + report_name = "Saved Worker Activity Report " + fetch_random_string() + self.wait_to_clear_and_send_keys(self.name_field, report_name) + text = self.get_selected_text(self.date_range_field_select) + print(text) + assert UserData.date_range[0].casefold() == text.casefold(), "Date Range does not match" + print("Date range is matching") + self.wait_to_click(self.save_report_button) + time.sleep(2) + self.driver.refresh() + self.wait_to_click(self.saved_reports_menu_link) + assert self.is_visible_and_displayed((By.XPATH, self.saved_report_created.format(report_name)), 120) + print("Report Saved successfully!") + return report_name + + def verify_case_type_data(self): + case_type_list = self.find_elements(self.case_created_column) + if len(case_type_list) > 0: + for item in case_type_list: + text = item.text + print("Cases created ", text) + if text == '0': + print("No Cases were created withing the given range") + else: + self.wait_to_click(item) + self.switch_to_next_tab() + time.sleep(10) + self.wait_for_element(self.case_list_table_title, 200) + self.scroll_to_bottom() + info = self.get_text(self.case_list_table_info) + info = str(info).split(" ") + print("Total records: ", info[-2]) + assert info[-2] == text, "Case created count mismatch" + print("Cases created count matched") + self.select_by_value(self.case_list_page_dropdown, '100') + time.sleep(10) + cases = self.find_elements(self.case_list_table) + if len(cases) > 0: + for case in cases: + name = case.text + assert name == UserData.case_reassign, "Case Type mismatch" + print("Case Type matching") + time.sleep(2) + self.driver.close() + time.sleep(2) + self.switch_back_to_prev_tab() + + def export_worker_activity_to_excel(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.case_type_textarea) + time.sleep(2) + assert not self.is_visible_and_displayed(self.case_type_list_empty, 10), "Case Type List is not empty" + self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.case_reassign))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + self.wait_to_click(self.export_to_excel) + self.wait_for_element(self.export_success) + print("Export to excel successful") + print("Sleeping for some time for the email to be sent") + time.sleep(30) + return list + + def compare_wa_with_email(self, link, web_data): + print(link) + print(web_data) + self.driver.get(link) + time.sleep(10) + newest_file = latest_download_file() + path = os.path.join(PathSettings.DOWNLOAD_PATH, newest_file) + print(path) + new_data = pd.read_excel(path, sheet_name=0, index_col=None) + print(new_data.values) + ext_list = [] + ext_list.extend(new_data.values.tolist()) + list = [] + for i in range(len(ext_list) - 1)[1:]: + list += ext_list[i] + print("List New: ", list) + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Excel and Searched results do not match" + print("Both Excel and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + if str(web_data[i]) == '---' and str(list[i]) == 'nan': + assert True, "Comparision failed for " + list[i] + " and " + web_data[i] + elif self.is_date(str(web_data[i])) == self.is_date(str(list[i])): + assert True, "Comparision failed for " + list[i] + " and " + web_data[i] + elif "%" in str(web_data[i]): + assert str(round(int(list[i]))) == str(web_data[i]).replace("%",""), "Comparision failed for " + list[i] + " and " + web_data[i] + else: + assert html.unescape(str(list[i])) == str(web_data[i]), "Comparision failed for " + list[i] + " and " + \ + web_data[i] + + def export_worker_activity_email(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + self.wait_to_click(self.case_type_textarea) + time.sleep(2) + assert not self.is_visible_and_displayed(self.case_type_list_empty, 10), "Case Type List is not empty" + self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.case_reassign))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[0]))) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.wait_for_element(self.form_activity_results) + col = self.find_elements(self.form_activity_results_cells) + list = [] + for c in col: + list.append(c.text) + print(list) + subject = UserData.email_worker_report + self.email_report_form_not_save(subject) + self.email_report_form(subject) + print("Export to excel successful") + print("Sleeping for some time for the email to be sent") + time.sleep(30) + return list, subject + + def email_report_form_not_save(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.email_form_cancel_btn) + print("Email report form closed properly") + + def email_report_form(self, subject): + self.wait_for_element(self.email_report_btn) + self.wait_to_click(self.email_report_btn) + self.wait_for_element(self.email_subject_field) + self.wait_to_clear_and_send_keys(self.email_subject_field, subject) + self.wait_to_click(self.send_email_btn) + assert self.is_visible_and_displayed(self.email_success_message), "Email report not sent successfully" + print("Email report sent successfully") + + def compare_wa_with_html_table(self, table_data, web_data): + list = table_data + print("Old data rows: ", len(web_data), "New data rows: ", len(list)) + print("Old List: ", web_data) + print("New list: ", list) + assert len(web_data) == len(list), "Data in Both Email Body and Searched results do not match" + print("Both Email Body and Searched results have same amount of data") + for i in range(len(list)): + print("Comparing ", html.unescape(str(list[i])), " with ", str(web_data[i])) + assert html.unescape(str(list[i])) == str(web_data[i]), "Cpmparision failed for " + list[i] + " and " + \ + web_data[i] + + def worker_activity_case_assign_data(self): + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + # self.wait_to_click(self.case_type_textarea) + # time.sleep(2) + # self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.sub_case))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + date_string, start_date, end_date = self.value_date_range_30_days() + # date_string, start_date, end_date = self.get_custom_dates_past(0, 0, 1) + # self.select_date_from_picker(start_date, end_date) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + # self.verify_users_in_the_group() + active_cases = self.find_elements(self.active_cases_column_list) + actives = [] + for items in active_cases: + actives.append(items.text) + total_cases = self.find_elements(self.total_cases_shared_column_list) + totals = [] + for items in total_cases: + totals.append(items.text) + print("Active Case: ", actives) + print("Total shared case: ", totals) + text = ("opened_on: [{} TO {}]").format(start_date, end_date) + print(text) + return actives, totals, text + + + def verify_assigned_cases_count(self, actives, totals): + print("Sleeping for some time for the cases to be assigned") + time.sleep(60) + self.wait_to_click(self.worker_activity_rep) + self.wait_for_element(self.apply_id) + assert self.WORKER_ACTIVITY_TITLE in self.driver.title, "This is not the Worker Activity page." + self.send_keys(self.users_field, UserData.user_group) + self.wait_to_click((By.XPATH, self.user_from_list.format(UserData.user_group))) + time.sleep(1) + self.select_by_text(self.view_by_dropdown, UserData.view_by[0]) + # self.wait_to_click(self.case_type_textarea) + # time.sleep(2) + # self.wait_to_click((By.XPATH, self.case_type_list_item.format(UserData.sub_case))) + self.wait_to_click(self.date_input) + self.wait_to_click((By.XPATH, self.date_range_type.format(UserData.date_range[2]))) + time.sleep(2) + self.wait_to_click(self.apply_id) + time.sleep(10) + self.wait_for_element(self.result_table, 300) + assert self.is_visible_and_displayed(self.report_content_id, 120), "Report not loaded" + print("Report loaded successfully!") + self.scroll_to_bottom() + # self.verify_users_in_the_group() + active_cases = self.find_elements(self.active_cases_column_list) + actives_new = [] + for items in active_cases: + actives_new.append(items.text) + total_cases = self.find_elements(self.total_cases_shared_column_list) + totals_new = [] + for items in total_cases: + totals_new.append(items.text) + print("Active Case: ", actives_new) + print("Total shared case: ", totals_new) + # for i in range(len(actives_new)): + # assert int(actives[i])-10 == actives_new[i], "Active Cases not reduced" + # print("Active cases reduced") + for i in range(len(totals_new)): + # print(int(totals[i]), int(totals_new[i])-10) + assert int(totals[i]) != int(totals_new[i]), "Total Shared Cases not changed" + print("Total Shared cases changed") + print("Cases successfully assigned") diff --git a/ElasticSearchTests/userInputs/__init__.py b/ElasticSearchTests/userInputs/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ElasticSearchTests/userInputs/user_inputs.py b/ElasticSearchTests/userInputs/user_inputs.py new file mode 100644 index 000000000..eab7ab501 --- /dev/null +++ b/ElasticSearchTests/userInputs/user_inputs.py @@ -0,0 +1,84 @@ +""""Contains test data that are used as user inputs across various areasn in CCHQ""" +import os + + +class UserData: + """User Test Data""" + USER_INPUT_BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + + # Pre-setup application and case names + village_application = "Village Health" + reassign_cases_application = 'Reassign Cases' + case_pregnancy = "pregnancy" + case_reassign = "reassign" + model_type_case = "case" + model_type_form = "form" + new_form_name = "Android Test Form" + app_login = "appiumtest" + app_password = "Pass@123" + two_fa_user = "2fa.commcare.user@gmail.com" + web_user = "[Web Users]" + all_data = "[All Data]" + mobile_testuser = "mobile_testuser" + copied_to_user = "mobile_testuser \"DO NOT DELETE! DO NOT DELETE!\"" + searched_user = "appiumtest \"DO NOT DELETE! DO NOT DELETE!\"" + automation_group_users = ["appiumtest", "formplayer_user"] + appiumtest_owner_id = "appiumtest@qa-automation.commcarehq.org" + appiumtest_owner_id_prod = "appiumtest@qa-automation-prod.commcarehq.org" + default_mw_role = "Mobile Worker Default" + user_group = "automation_user" + user_group_shared = "automation_user [case sharing]" + assign_case_user = "mobile_testuser" + view_by = ["Users", "Groups"] + filter_dates_by = ["Completion Time", "Submission Time"] + location = "updated_on" + arrows_code = ['color: #8b0000', 'color: rgb(139, 0, 0)', 'color: #006400', 'color: rgb(0, 100, 0)'] + proj_perf_excel_tabs = ['Six Month Performance Summary', 'Inactive Users', 'Low Performing Users', + 'New Performing Users'] + date_range = ["Last 7 Days", "Last Month", "Last 30 Days", "Custom Range"] + wa_column_names = ["# Forms Submitted", "Avg # Forms Submitted", "Last Form Submission", "# Cases Created", + "# Cases Closed", "# Active Cases", "# Total Cases (Owned & Shared)", "% Active Cases"] + wa_column_group_names = ["Form Data", "Case Data", "Case Activity"] + + ca_column_names = ["# Updated or Closed", "# Active", "# Closed"] + ca_column_group_names = ["Cases in Last 30 Days", "Cases in Last 60 Days", "Cases in Last 90 Days"] + + fct_column_names = ["User", "Average", "Std. Dev.", "Shortest", "Longest", "No. of Forms"] + fcst_column_names = ["User", "Completion Time", "Submission Time", "Form Name", "Difference"] + pagination = ['10', '25', '50', '100'] + # Phone Number + area_code = "91" + + # web app + app_type = "Applications" + case_list_name = 'Case List' + form_name = 'Registration Form' + login_as = 'henry' + update_case_change_link = "Case Change" + case_register_form = "Case Register" + case_update_form = "Update Case" + case_update_name = "reassign_change" + daily_form_groups = ["Active Mobile Workers", "Deactivated Mobile Workers"] + deactivated_user = "deactivate_test_user" + + # Date Filter + date_having_submissions = "2022-01-18 to 2022-02-18" + + worker_report = "Worker Activity: Requested export excel data" + email_worker_report = "Worker Activity Report sent via scripts" + daily_form_report = "Daily Form Activity: Requested export excel data" + email_daily_form_report = "Daily Form Activity Report sent via scripts" + case_report = "Case Activity: Requested export excel data" + email_case_report = "Case Activity Report sent via scripts" + email_proj_perf_report = "Project Performance Report sent via scripts" + email_sub_by_form_report = "Submissions By Form Report sent via scripts" + email_form_comp_report = "Form Completion Time Report sent via scripts" + + reasign_modules_forms = {"Case Change": ["Case Register", "Update Case"], + "Case List": ["Android Test Form", "Followup Form", "Registration Form"]} + + default_app_mod_form = ["Show all Forms of this Application Type...", "Show all Forms in selected Application", "Show all Forms in selected Module"] + default_app_mod_form_fct = ["Select Application...", "Select a Menu", "Select a Form"] + app_type_list = ["Show all Application Types", "Active CommCare Applications", "Deleted CommCare Applications"] + fct_app_type_list = ["Select an Application Type", "Active CommCare Applications", "Deleted CommCare Applications"] + view_form_tabs = ["Form Properties", "Case Changes", "Form Metadata", "Raw XML"] \ No newline at end of file diff --git a/HQSmokeTests/testPages/email/email_verification.py b/HQSmokeTests/testPages/email/email_verification.py index c766022d9..cce7a5b3e 100644 --- a/HQSmokeTests/testPages/email/email_verification.py +++ b/HQSmokeTests/testPages/email/email_verification.py @@ -4,6 +4,7 @@ from imap_tools import AND, OR, NOT from bs4 import BeautifulSoup import re +import pandas as pd from HQSmokeTests.userInputs.user_inputs import UserData @@ -35,3 +36,140 @@ def get_hyperlink_from_latest_email(self, subject, url): print(len(links)) print(links[0]) return str(links[0]) + + def get_email_body_from_latest_email(self, subject, url): + if 'www' in url: + from_email = UserData.from_email_prod + else: + from_email = UserData.from_email + print(subject) + with MailBox(self.imap_host).login(self.imap_user, self.imap_pass, 'INBOX') as mailbox: + bodies = [msg.html for msg in + mailbox.fetch(AND(subject=subject, from_=from_email, date=datetime.date.today()))] + print(len(bodies)) + n = '' + if "Worker Activity" in subject or "Case Activity" in subject: + n = 2 + else: + n = 1 + soup = BeautifulSoup(str(bodies[len(bodies)-1]), "html.parser") + tr = [] + table = [] + + for row in soup.select("tr")[n:-1]: + for td in row.select("td"): + td = td.get_text() + td = str(td).replace("\\r", '') + td = str(td).replace("\\n", '') + td = re.sub("\r\n+", "", td) + tr.append(td.strip()) + table.append(tr) + print(len(table)) + print(table[-1]) + return table[-1] + + def get_email_body_from_latest_email_proj_perf(self, subject, url): + if 'www' in url: + from_email = UserData.from_email_prod + else: + from_email = UserData.from_email + print(subject) + with MailBox(self.imap_host).login(self.imap_user, self.imap_pass, 'INBOX') as mailbox: + bodies = [msg.html for msg in + mailbox.fetch(AND(subject=subject, from_=from_email, date=datetime.date.today()))] + soup = BeautifulSoup(str(bodies[len(bodies)-1]), "html.parser") + tr = [] + td = [] + table = [] + tab_low = [] + tab_inactive = [] + tab_high = [] + for tables in soup.findAll('table'): + table.append(tables) + table_low = table[0] + table_inactive = table[1] + table_high = table[2] + + if len(table_low.findAll('td')) > 0: + print(len(table_low.findAll('td'))) + for row in table_low.select("tr"): + tr = [] + for cells in row.select("td"): + td = [] + text = cells.get_text() + text = str(text).replace("\\r", '') + text = str(text).replace("\\n", '') + text = re.sub("\r\n+", "", text) + text = str(text).replace(u'\xa0', u'') + text = str(text).strip() + text = re.sub(" +", "--", text) + if text == '': + td.append("No data available in table") + else: + td.append(text) + tr.extend(td) + if tr == []: + print("empty row") + else: + tab_low.extend(tr) + else: + tab_low = ['No data available in table'] + + print("tab low", tab_low) + + + if len(table_inactive.findAll('td')) > 0: + print(len(table_inactive.findAll('td'))) + for row in table_inactive.select("tr"): + tr = [] + for cells in row.select("td"): + td = [] + text = cells.get_text() + text = str(text).replace("\\r", '') + text = str(text).replace("\\n", '') + text = re.sub("\r\n+", "", text) + text = str(text).replace(u'\xa0', u'') + text = str(text).strip() + text = re.sub(" +", "--", text) + if text == '': + td.append("No data available in table") + else: + td.append(text) + tr.extend(td) + if tr == []: + print("empty row") + else: + tab_inactive.extend(tr) + else: + tab_inactive = ['No data available in table'] + + print("tab inactive", tab_inactive) + + if len(table_high.findAll('td')) > 0: + print(len(table_high.findAll('td'))) + for row in table_high.select("tr"): + tr = [] + for cells in row.select("td"): + td = [] + text = cells.get_text() + text = str(text).replace("\\r", '') + text = str(text).replace("\\n", '') + text = re.sub("\r\n+", "", text) + text = str(text).replace(u'\xa0', u'') + text = str(text).strip() + text = re.sub(" +", "--", text) + if text == '': + td.append("No data available in table") + else: + td.append(text) + tr.extend(td) + if tr == []: + print("empty row") + else: + tab_high.extend(tr) + else: + tab_high = ['No data available in table'] + + print("tab high", tab_high) + table_data = [tab_low + tab_inactive + tab_high] + return table_data \ No newline at end of file diff --git a/common_utilities/selenium/base_page.py b/common_utilities/selenium/base_page.py index c9cdada7d..3f156c33c 100644 --- a/common_utilities/selenium/base_page.py +++ b/common_utilities/selenium/base_page.py @@ -1,6 +1,7 @@ import time import datetime +from dateutil.parser import parse from selenium.webdriver.support.select import Select from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException, \ UnexpectedAlertPresentException, StaleElementReferenceException, NoSuchElementException @@ -90,7 +91,7 @@ def wait_to_get_value(self, locator, timeout=20): def wait_for_element(self, locator, timeout=20): clickable = ec.element_to_be_clickable(locator) WebDriverWait(self.driver, timeout, poll_frequency=5).until(clickable, - message="Couldn't find locator: " + str(locator)) + message="Couldn't find locator: " + str(locator)) def wait_and_sleep_to_click(self, locator, timeout=90): element = None @@ -223,7 +224,8 @@ def is_visible_and_displayed(self, locator, timeout=50): try: visible = ec.visibility_of_element_located(locator) element = WebDriverWait(self.driver, timeout, poll_frequency=10).until(visible, - message="Element" + str(locator) + "not displayed") + message="Element" + str( + locator) + "not displayed") is_displayed = element.is_displayed() except TimeoutException: is_displayed = False @@ -233,7 +235,8 @@ def is_present_and_displayed(self, locator, timeout=50): try: visible = ec.presence_of_element_located(locator) element = WebDriverWait(self.driver, timeout, poll_frequency=10).until(visible, - message="Element" + str(locator) + "not displayed") + message="Element" + str( + locator) + "not displayed") is_displayed = element.is_displayed() except TimeoutException: is_displayed = False @@ -334,14 +337,16 @@ def scroll_to_element(self, locator): self.driver.execute_script("arguments[0].scrollIntoView();", element) def wait_and_find_elements(self, locator, cols, timeout=500): - elements = WebDriverWait(self.driver, timeout, poll_frequency=10).until(lambda driver: len(driver.find_elements(*locator)) >= int(cols)) + elements = WebDriverWait(self.driver, timeout, poll_frequency=10).until( + lambda driver: len(driver.find_elements(*locator)) >= int(cols)) return elements def wait_till_progress_completes(self, type="export"): if type == "export": if self.is_present((By.XPATH, "//div[contains(@class,'progress-bar')]")): WebDriverWait(self.driver, 600, poll_frequency=10).until( - ec.visibility_of_element_located((By.XPATH, "//div[contains(@class,'progress-bar')][.//span[@data-bind='text: progress'][.='100']]"))) + ec.visibility_of_element_located((By.XPATH, + "//div[contains(@class,'progress-bar')][.//span[@data-bind='text: progress'][.='100']]"))) elif type == "integration": WebDriverWait(self.driver, 600, poll_frequency=10).until( ec.invisibility_of_element_located((By.XPATH, "//div[contains(@class,'progress-bar')]"))) @@ -350,7 +355,8 @@ def is_clickable(self, locator, timeout=50): try: clickable = ec.element_to_be_clickable(locator) element = WebDriverWait(self.driver, timeout, poll_frequency=10).until(clickable, - message="Element" + str(locator) + "not displayed") + message="Element" + str( + locator) + "not displayed") is_clickable = element.is_enabled() except TimeoutException: is_clickable = False @@ -365,3 +371,25 @@ def wait_for_ajax(self): wait.until(lambda driver: self.driver.execute_script('return jQuery.active') == 0) wait.until(lambda driver: self.driver.execute_script('return document.readyState') == 'complete') + def is_date(self, string, fuzzy=False): + """ + Return whether the string can be interpreted as a date. + + :param string: str, string to check for date + :param fuzzy: bool, ignore unknown tokens in string if True + """ + try: + parse(string, fuzzy=fuzzy) + return True + + except ValueError: + return False + + def get_all_dropdown_options(self, source_locator): + select_source = Select(self.driver.find_element(*source_locator)) + list_opt = [] + for opt in select_source.options: + print(opt.text) + list_opt.append(opt.text) + print("Option list", list_opt) + return list_opt