Skip to content

QA-7204 fix for staging failures and updated locust script #375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion HQSmokeTests/testPages/android/android_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def __init__(self, settings):
"appium:automationName": "UIAutomator2",

# Set URL of the application under test
"appium:app": "bs://69575555b507f2c867243ffee58c5a46badcce8d",
"appium:app": "bs://f078e237c9800a05c57e9cbd8f27da71ec787d89",

"appium:autoGrantPermissions": "true",
"appium:newCommandTimeout": 3600,
Expand Down
20 changes: 20 additions & 0 deletions HQSmokeTests/testPages/messaging/messaging_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def __init__(self, driver):
self.add_lang = (By.XPATH, "//button[@data-bind='click: addLanguage, disable: addLanguageDisabled']")
self.lang_input_textarea = (By.XPATH, "(//span[@role='combobox'])[last()]")
self.select_first_lang = (By.XPATH, "(//li[@role='option'])[1]")
self.select_eng_lang = (By.XPATH, "(//li[@role='option'][contains(.,'en (English)')])[1]")
self.select_second_lang = (By.XPATH, "(//li[@role='option'])[2]")
self.selected_lang_name = (By.XPATH, "(//td//p[contains(@data-bind,'message')])[last()]")
self.language_list = (By.XPATH, "//ul[@role='listbox']")
Expand Down Expand Up @@ -356,6 +357,16 @@ def general_settings_page(self):
def delete_languages(self):
self.wait_to_click(self.languages)
time.sleep(1)
lang_list = self.find_elements(self.languages_present)
if len(lang_list) == 1:
for item in lang_list:
print(item.text)
if item.text == 'English':
print("Default language present as English")
else:
self.add_eng_lang()
print("English updated successfully")

lang_list = self.find_elements(self.languages_present)
if len(lang_list) > 1:
for item in lang_list:
Expand All @@ -371,6 +382,15 @@ def delete_languages(self):
else:
print("Only English is Present and no other languages")

def add_eng_lang(self):
self.wait_to_click(self.lang_input_textarea)
time.sleep(2)
self.wait_for_element(self.language_list)
self.wait_to_click(self.select_eng_lang)
time.sleep(2)
lang = self.get_text(self.selected_lang_name)
print("Language selected is: ", lang)
self.wait_to_click(self.save_lang)

def languages_page(self):
self.wait_to_click(self.languages)
Expand Down
24 changes: 10 additions & 14 deletions HQSmokeTests/testPages/users/org_structure_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def __init__(self, driver):
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[contains(@class,'alert-success')]")
self.success_msg_remove = (By.XPATH, "//div[contains(@class,'alert-success')]/a")
self.success_msg_remove = (By.XPATH, "//div[contains(@class,'alert-success')]//*[contains(@class,'close')]")
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 + "']")
Expand Down Expand Up @@ -110,9 +110,10 @@ def __init__(self, driver):
self.confirm_user_field_delete = (
By.XPATH, "(//a[.='Cancel']//following-sibling::button[contains(@class,'danger')])[last()]")
self.sign_off_input = (By.XPATH, "//input[contains(@data-bind,'signOff')]")
self.test_location_delete_button = (By.XPATH, "//div/span[@class='loc_name'][contains(.,'location_')]//preceding::div[1]/button[contains(.,'Delete')]")
self.test_location_delete_button = (By.XPATH, "//div/span[contains(@class,'loc_name')][contains(.,'location_')]//preceding::div[1]/button[contains(.,'Delete')]")
self.test_location_delete_button_last = "(//div/span[contains(@class,'loc_name')][contains(.,'location_')]//preceding::div[1]/button[contains(.,'Delete')])[{}]"
self.test_location_delete_confirm = (By.XPATH, "//input[contains(@data-bind,'signOff')]//following::button[.='Delete']")
self.success_msg_xpath


def organisation_menu_open(self):
self.wait_to_click(self.org_menu_link_text)
Expand Down Expand Up @@ -208,8 +209,6 @@ def upload_locations(self):
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)
time.sleep(5)
self.delete_test_location_field()
self.delete_test_locations()
self.delete_test_org_level()
Expand Down Expand Up @@ -279,14 +278,11 @@ def delete_test_locations(self):
time.sleep(3)
list_profile = self.find_elements(self.test_location_delete_button)
print("Number of Test Locations: ", len(list_profile))
if len(list_profile) > 0:
count = 0
for item in list_profile:
if len(list_profile) != 0:
for i in range(len(list_profile)):
time.sleep(3)
item.click()
# 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.scroll_to_element((By.XPATH, self.test_location_delete_button_last.format(i+1)))
self.js_click((By.XPATH, self.test_location_delete_button_last.format(i+1)))
time.sleep(5)
self.wait_for_element(self.sign_off_input)
self.send_keys(self.sign_off_input, "1"+ Keys.TAB)
Expand All @@ -296,8 +292,8 @@ def delete_test_locations(self):
self.wait_for_element(self.success_msg_xpath)
self.click(self.success_msg_remove)
time.sleep(2)
count = count+1
print("Deleted location ", count)
list_profile = self.find_elements(self.test_location_delete_button)
print("Deleted location number: ", str(i+1))
else:
print("No test locations present in the list")
except Exception:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
import logging
import random
import time

from locust import SequentialTaskSet, between, events, tag, task
from locust.exception import InterruptTaskSet

from common.args import file_path
from common.utils import RandomItems, load_json_data
from user.models import UserDetails, BaseLoginCommCareUser


@events.init_command_line_parser.add_listener
def _(parser):
# """
# Use below command to execute this test:
# locust -f .\LocustScripts\update-scripts\commcarehq-referrals-search-for-beds-mw-login_sin
# gle_case.py --domain co-carecoordination-perf --build-id b62974969e57051ad70160a798ed79e8 --app-id 3271c8c86a5344e59554dfcb3e4628b8 --app-config .\LocustScripts\upd
# ate-scripts\project-config\co-carecoordination-perf\app_config_referrals_platform.json --user-details .\LocustScripts\update-scripts\project-config\co-c
# arecoordination-perf\mobile_worker_credentials.json

parser.add_argument("--domain", help="CommCare domain", required=True, env_var="COMMCARE_DOMAIN")
parser.add_argument("--build-id", help="CommCare build id", required=True, env_var="COMMCARE_APP_ID")
parser.add_argument("--app-id", help="CommCare app id", required=True, env_var="COMMCARE_APP_ID")
parser.add_argument("--app-config", help="Configuration of CommCare app", required=True)
parser.add_argument("--user-details", help="Path to user details file", required=True)


APP_CONFIG = {}
USERS_DETAILS = RandomItems()

class WorkloadModelSteps(SequentialTaskSet):
wait_time = between(5, 15)

def on_start(self):
self.FUNC_HOME_SCREEN = APP_CONFIG['FUNC_HOME_SCREEN']
self.FUNC_SEARCH_FOR_BEDS_MENU = APP_CONFIG['FUNC_SEARCH_FOR_BEDS_MENU']
self.FUNC_CREATE_PROFILE_AND_REFER_FORM = APP_CONFIG['FUNC_CREATE_PROFILE_AND_REFER_FORM']
self.FUNC_CREATE_PROFILE_AND_REFER_FORM_QUESTIONS = self.FUNC_CREATE_PROFILE_AND_REFER_FORM["questions"]
self.FUNC_CREATE_PROFILE_AND_REFER_FORM_SUBMIT = APP_CONFIG['FUNC_CREATE_PROFILE_AND_REFER_FORM_SUBMIT']
self.FUNC_OUTGOING_REFERRALS_MENU = APP_CONFIG["FUNC_OUTGOING_REFERRALS_MENU"]
self.FUNC_ENTER_STATUS = APP_CONFIG["FUNC_ENTER_STATUS"]
self.FUNC_ENTER_GENDER = APP_CONFIG["FUNC_ENTER_GENDER"]
self.FUNC_OUTGOING_REFERRAL_DETAILS_FORM = APP_CONFIG["FUNC_OUTGOING_REFERRAL_DETAILS_FORM"]
self.FUNC_OUTGOING_REFERRAL_DETAILS_FORM_SUBMIT = APP_CONFIG["FUNC_OUTGOING_REFERRAL_DETAILS_FORM_SUBMIT"]
self.cases_per_page = 100

@tag('home_screen')
@task
def home_screen(self):
self.user.hq_user.navigate_start(expected_title=self.FUNC_HOME_SCREEN['title'])

@tag('search_for_beds_menu')
@task
def search_for_beds_menu(self):
data = self.user.hq_user.navigate(
"Open Search for Beds Menu",
data={
"selections": [self.FUNC_SEARCH_FOR_BEDS_MENU['selections']],
"cases_per_page": self.cases_per_page,
},
expected_title=self.FUNC_SEARCH_FOR_BEDS_MENU['title']
)
if data:
self.page_count = data["pageCount"]

@tag('select_cases')
@task
def select_cases(self):
logging.info(
"Selecting Random Cases - mobile worker:" + self.user.user_detail.username + "; request: navigate_menu"
)
total_qty_cases_to_select = random.randrange(1, 2)
self.selected_case_ids = set()

# As is, this doesn't handle if there aren't enough cases to select. Also it won't handle well
# situations where the ratio of # cases to select: # cases available to select are too high
# since the same random case could be chosen multiple times. But for our use case, this ratio will be very low
max_num_iterations = total_qty_cases_to_select
i = 0
while len(self.selected_case_ids) < total_qty_cases_to_select:
random_page_num = random.randrange(0, self.page_count)
offset = random_page_num * self.cases_per_page

random_qty_cases_to_select_per_page = random.randrange(1, total_qty_cases_to_select + 1)
qty_cases_remaining_to_select = total_qty_cases_to_select - len(self.selected_case_ids)
qty_to_select = min(random_qty_cases_to_select_per_page, qty_cases_remaining_to_select)

extra_json = {
"selections": [self.FUNC_SEARCH_FOR_BEDS_MENU['selections']],
"cases_per_page": self.cases_per_page,
"offset": offset,
}

data = self.user.hq_user.navigate(
"Paginate for Case Selection",
data=extra_json,
expected_title=self.FUNC_SEARCH_FOR_BEDS_MENU['title']
)

entities = data["entities"]
ids = [entity["id"] for entity in entities if entity["id"] not in self.selected_case_ids]
if len(ids) < qty_to_select:
self.selected_case_ids.update(ids)
else:
for _ in range(qty_to_select):
random_case_index = random.randrange(0, len(ids))
self.selected_case_ids.add(ids[random_case_index])

# crude way to avoid looping infinitely
i += 1
assert i < max_num_iterations, "exceeded allowed number of iterations to select cases for mobile worker " + self.user.user_detail.username
rng = random.randrange(1, 3)
time.sleep(rng)
logging.info("selected cases are " + str(
self.selected_case_ids
) + " for mobile worker " + self.user.user_detail.username
)

@tag('enter_create_profile_and_refer_form')
@task
def enter_create_profile_and_refer_form(self):
logging.info("Entering form - mobile worker:" + self.user.user_detail.username + "; request: navigate_menu")

extra_json = {
"selected_values": (list(self.selected_case_ids)),
"query_data": {},
"selections": [self.FUNC_SEARCH_FOR_BEDS_MENU['selections'], "use_selected_values"],
}

data = self.user.hq_user.navigate(
"Enter 'Create Profile and Refer' Form",
data=extra_json,
expected_title=self.FUNC_CREATE_PROFILE_AND_REFER_FORM['title']
)
self.session_id = data['session_id']

@tag('answer_create_profile_and_refer_form_questions')
@task
def answer_create_profile_and_refer_form_questions(self):
logging.info("Answering Questions - mobile worker:" + self.user.user_detail.username + "; request: answer")
for question in self.FUNC_CREATE_PROFILE_AND_REFER_FORM_QUESTIONS.values():
extra_json = {
"ix": question["ix"],
"answer": question["answer"],
"session_id": self.session_id,
}
self.user.hq_user.answer(
"Answer 'Create Profile and Refer' Question",
data=extra_json,
)
rng = random.randrange(1, 3)
time.sleep(rng)

@tag('submit_create_profile_and_refer_form')
@task
def submit_create_profile_and_refer_form(self):
logging.info("Submitting form - mobile worker:" + self.user.user_detail.username + " and session id: " + str(self.session_id) +" ; request: submit_all")
utc_time_tuple = time.gmtime(time.time())
formatted_date = "{:04d}-{:02d}-{:02d}".format(utc_time_tuple.tm_year, utc_time_tuple.tm_mon,
utc_time_tuple.tm_mday
)
answers = {
"3": "OK",
"8": "OK",
"9": "OK",
"1,1,0": "OK",
"1,1,1": 21,
"1,1,2": 2,
"1,1,3": formatted_date,
"1,1,4": "Symptoms encouraged visit",
"1,1,5": "Inpatient",
"1,1,6": "NOT HEADACHE",
"1,1,7": 3,
"1,1,8": None,
"1,1,9": None,
"1,1,10": None,
"1,1,11": None,
"1,1,12": None,
"1,1,13": None,
# "1,3": 1,
"1,7,0": [1],
"4_0,5,0,0": "OK",
"4_0,5,0,1": "OK",
"4_0,5,0,2": "OK",
"4_0,5,0,3": "OK",
"4_0,5,0,4": "OK",
"4_0,5,0,5": "OK",
"4_0,6": None
}
input_answers = {d["ix"]: d["answer"] for d in self.FUNC_CREATE_PROFILE_AND_REFER_FORM_QUESTIONS.values()}
answers.update(input_answers)

extra_json = {
"answers": answers,
"prevalidated": True,
"debuggerEnabled": True,
"session_id": self.session_id,
}

self.user.hq_user.submit_all(
"Submit Create Profile and Refer Form",
extra_json,
status="success"
# expected_response_message=self.FUNC_CREATE_PROFILE_AND_REFER_FORM_SUBMIT['submitResponseMessage']
)
logging.info("Create Profile and Refer Form submitted successfully - mobile worker:" + self.user.user_detail.username + " and session id: " + str(self.session_id) +" ; request: submit_all")


@events.init.add_listener
def _(environment, **kw):
try:
app_config_path = file_path(environment.parsed_options.app_config)
APP_CONFIG.update(load_json_data(app_config_path))
logging.info("Loaded app config")
except Exception as e:
logging.error("Error loading app config: %s", e)
raise InterruptTaskSet from e
try:
user_path = file_path(environment.parsed_options.user_details)
user_data = load_json_data(user_path)["user"]
USERS_DETAILS.set([UserDetails(**user) for user in user_data])
logging.info("Loaded %s users", len(USERS_DETAILS.items))
except Exception as e:
logging.error("Error loading users: %s", e)
raise InterruptTaskSet from e


class LoginCommCareHQWithUniqueUsers(BaseLoginCommCareUser):
tasks = [WorkloadModelSteps]
wait_time = between(5, 10)

def on_start(self):
super().on_start(
domain=self.environment.parsed_options.domain,
host=self.environment.parsed_options.host,
user_details=USERS_DETAILS,
build_id=self.environment.parsed_options.build_id,
app_id=self.environment.parsed_options.app_id
)
Loading