Index: shared/scripts/configuration/config.py =================================================================== diff -u -r6f233592334983db7867dc20e067cc55d528c2cd -rde4dd0bb518628a7cdb691f5af71f8d2ffa02d52 --- shared/scripts/configuration/config.py (.../config.py) (revision 6f233592334983db7867dc20e067cc55d528c2cd) +++ shared/scripts/configuration/config.py (.../config.py) (revision de4dd0bb518628a7cdb691f5af71f8d2ffa02d52) @@ -40,6 +40,10 @@ SERVICE_CONF_LOCATION = os.environ['HOME']+"/Projects/application/resources/settings/Service.conf" TREATMENT_LOG_LOCATION = '/home/denali/Desktop/sd-card/treatment/*.log' +BLOOD_PRIMING_TEXT = "Blood Priming" +SALINE_UNIT = "mL" + + ACCEPTED = True REJECTED = False ENABLED = True @@ -376,8 +380,8 @@ VALID = True INVALID = False + #post treatment review -ACID_CONCENTRATE_POST = ["Fres. Naturalyte", "08-1251-1", "08-2251-0", "08-3251-9", "08-3251-9"] BRIGHTNESS_MIN_VAL = 20 BRIGHTNESS_MAX_VAL = 100 VOLUME_MIN_VAL = 20 @@ -429,3 +433,5 @@ NUM_OF_REQUEST_REJECT_REASONS = 46 #Number of settings change reject codes + + Index: shared/scripts/configuration/strings.py =================================================================== diff -u -r6f233592334983db7867dc20e067cc55d528c2cd -rde4dd0bb518628a7cdb691f5af71f8d2ffa02d52 --- shared/scripts/configuration/strings.py (.../strings.py) (revision 6f233592334983db7867dc20e067cc55d528c2cd) +++ shared/scripts/configuration/strings.py (.../strings.py) (revision de4dd0bb518628a7cdb691f5af71f8d2ffa02d52) @@ -23,6 +23,11 @@ PRE_TREATMENT_SCREENS = ["Create" , "Sample" , "Consumables" , "Disposables" , "Prime" , "Ultrafiltration" , "BP/HR" , "Connection" , "Start"] POST_TREATMENT_SCREENS = ["Disconnection", "Review", "Disposables", "Disinfection"] +BLOOD_PRIMING_UNIT = "mL" +BLOOD_PRIMING_VALUE_0 = "0" +BLOOD_PRIMING_DEFAULT_VALUE = BLOOD_PRIMING_VALUE_0 + " " + BLOOD_PRIMING_UNIT + + SALINE_UNIT = "mL" BLOOD_PRIMING_UNIT = "mL" BLOOD_PRIMING_VALUE_0 = "0" @@ -297,10 +302,21 @@ #post treatment review TREATMENT_REVIEW_TITLE_TEXT = "Treatment Review" +HEPARIN_TYPE = "UFH 1,000 IU/mL" +ACID_CONCENTRATE = ["08-1251-1", "08-2251-0", "08-3251-9", "08-3251-9"] +BICARBONATE_CONCENTRATE = "Fres. Centrisol" +DIALYZER_TYPE = ["BB Diacap Pro 13H", "BB Diacap Pro 16H", "BB Diacap Pro 19H", "F Optiflux F160NRe", "F Optiflux F180NRe"] +TREATMENT_REVIEW_TITLE_TEXT = "Treatment Review" +EXPORT_TEXT = "Export" +CODE_TEXT = "Code: " +CODE_TEXT_AFTER_LOGGING = "Code: ..." + POST_TREATMENT_REVIEW_SCREEN_UNITS = { "Patient ID" : "", + "Heparin Bolus Volume": "mL", "Heparin Stop" : "min", - "Device ID" : "", + "Heparin Dispense Rate" : "mL/hr", + "Heparin Bolus Volume" : "mL", "Heparin Delivered Volume": "mL", "Blood Flow Rate" : "mL/min", "Treatment Start DateTime" : "", @@ -322,18 +338,11 @@ "Target UF Rate": "mL/min", "Sodium Concentration" : "mEg/L", "Actual UF Rate": "mL/min", - "Dialysate Temperature" :"°C", + "Dialysate Temperature" :"C", "Saline Bolus Volume" : "mL", "Dialyzer Type" : "", - "Average Blood Flow" : "mL/min", - "Heparin Type" : "IU/mL", - "Average Dialysate Flow" : "mL/min", - "Heparin Concentration" : "IU/mL", - "Average Dialysate Temp" : "°C", - "Heparin Bolus Volume": "mL", - "Average Arterial Pressure" : "mmHg", - "Heparin Dispense Rate" : "mL/hr", - "Average Venous Pressure" : "mmHg", + "Heparin Type" : "", + "Heparin Concentration" : "IU/mL", } #Information @@ -342,7 +351,6 @@ SERIVCES_TITLE = "Service" SERVICES_PARAMETERS = ["HD Last Service Date", "HD Next Service Date", "DG Last Service Date", "DG Next Service Date"] - #volume and brightness VOLUME_AND_BRIGHTNESS_TEXT = "Volume And Brightness" BRIGHTNESS_TEXT = "Brightness" @@ -769,3 +777,4 @@ DIALYSATE_TEMPERATURE = "Dialysate Temperature" BLOOD_PRESSURE_MEASUREMENT_INTERVAL = "Blood Pressure Measurement Interval" RINSEBACK_FLOW_RATE = "Rinseback Flow Rate" + Index: shared/scripts/configuration/utility.py =================================================================== diff -u -r79c10476a6ccb22f3faf9b37be90463c8e28fe46 -rde4dd0bb518628a7cdb691f5af71f8d2ffa02d52 --- shared/scripts/configuration/utility.py (.../utility.py) (revision 79c10476a6ccb22f3faf9b37be90463c8e28fe46) +++ shared/scripts/configuration/utility.py (.../utility.py) (revision de4dd0bb518628a7cdb691f5af71f8d2ffa02d52) @@ -6,24 +6,53 @@ # WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. # # @file utils.py -# -# @author (last) Joseph varghese +# @author (last) LTTS # @date (last) 15-Jan-2022 # ############################################################################ + import builtins +import csv import names import os import glob +import math +import names import object -import test -import time +import sys import squish -from configuration import config +import time +import test +from builtins import format from builtins import int as pyInt - - +from builtins import str as pyStr +from configuration import config +from dialin.ui import utils +from dialin.utils import * +from dialin.common.msg_ids import MsgIds +from dialin.ui.hd_simulator import HDSimulator +from dialin.protocols import DenaliMessage, DenaliCanMessenger, DenaliChannels +from datetime import datetime + + +LOG_LOCATION = "/home/denali/Desktop/sd-card/log/*.log" + +def color_verification(exp_val = "Red", act_val = "#c53b33"): + test.compare(config.COLOR_CODES[color_name],(act_val.color[name])) + + +def get_text_object(screen_obj, txt): + """ + To obtain a text object based on text provided + @param screen_obj: provides the container on which the txt must be present + @returns a real name object + """ + names.o_text_object["container"] = screen_obj + names.o_text_object["text"] = txt + return names.o_text_object + + def get_bullet_object(screen_obj, num): """ To obtain a bullet object based on occurrence provided. @@ -55,7 +84,7 @@ check if an object is inside a container @param obj - child UI object @param container - container UI object - @return boolean true and false + @return boolean True/False """ container = squish.findObject(container) containerPos = container.mapToGlobal(squish.QPoint(0, 0)) @@ -73,108 +102,71 @@ return False - -def scroll_to_zone(zone=None, screen_object=None, direction = None): +def scroll_to_value_on_pop_up(value=None, container=None): """ - scroll to the UI, if object is hidden - @param zone - object to be find out. - @param screen_object - object of the screen. - @return boolean + scroll to the to the value if object is hidden + @param value - (obj) value object + @param container - (obj) Container of the value + @return boolean true and false """ counter = 0 while counter <= 100: try: counter += 1 + squish.findObject(value) squish.snooze(0.5) - squish.findObject(zone) - squish.snooze(0.5) - if check_if_object_is_within_the_container(obj=zone, container=screen_object): + if check_if_object_is_within_the_container(obj=value, container=container): return True else: raise RuntimeError except RuntimeError: - ScreenObj = squish.findObject(screen_object) + ScreenObj = squish.waitForObject(container) screenHeight = pyInt(ScreenObj.height) screenWidth = pyInt(ScreenObj.width) - if direction is None: - squish.mouseWheel(ScreenObj, (screenWidth-100), - 107, 0, -(screenHeight-460), squish.Qt.NoModifier) - else: - squish.mouseWheel(ScreenObj, (screenWidth-100), - -(screenHeight-700), 0, 50, squish.Qt.NoModifier) - - raise LookupError("zone object is not in view to the user after " + \ - "trying 100 times") + squish.mouseWheel(ScreenObj, screenWidth//2, screenHeight//2, 0, -50, squish.Qt.NoModifier) + raise LookupError("value object is not in view to the user after trying 100 times") +def pressure_pop_up_text_obj(text): + names.o_pop_up_pressure_text_obj["text"] = text + return names.o_pop_up_pressure_text_obj + return names.o_bullet_object + +def verify_bullet_navigation(num, num_of_instructions, screen_obj): + """ + Method to verify status of bullets based + on number of instruction screen + @param num - (int) number of indicator + @param num_of_instructions- (int) count the number of instructions + @param object - screen_obj - (str) Screen object + """ + test.startSection("instruction bullet verification for screens") + for instruction in range(1, num_of_instructions): + bullet_children = object.children(squish.waitForObjectExists(get_bullet_object(screen_obj,(0 + instruction) - 1))) + bullet_circle_color = bullet_children[0].color.name + bullet_border_color = bullet_children[0].border.color.name + if instruction <= num: + test.compare(bullet_circle_color, config.COMPLETE_COLOR) + test.compare(bullet_border_color,config.COMPLETE_COLOR) + test.log(str(instruction) + " Complete bullet") + else: + test.compare(bullet_circle_color, config.CURRENT_COLOR) + test.compare(bullet_border_color,config.INCOMPLETE_COLOR) + test.log(str(instruction) + " Incomplete bullet") + test.endSection() + def convert_seconds_into_min_and_sec(seconds, time_format="%M:%S"): """ Method to convert seconds into minute format. @param seconds - time in seconds. @param time_format (str) - time format. @return (int) - minute time """ - seconds = builtins.int(seconds) + seconds = int(seconds) min_and_sec = time.strftime(time_format, time.gmtime(seconds)) return min_and_sec - -def get_extracted_file(): - """ - This function is the handler for getting file from log folder. - - This handler will go inside log folder and looks for newly added log based on current time. - if it satisfied that condition, it will return the exact path of newly created log. - - @return latest_file - (string) returns latest file that append on log folder from sd-data - """ - try: - list_of_files = glob.glob(config.TREATMENT_LOG_LOCATION) - latest_file = max(list_of_files, key=os.path.getctime) - return latest_file - except: - test.fail("log file is not created during application interaction") - return False - - -def get_text_object(screen_obj, txt): - """ - To obtain a text object based on text provided - @param screen_obj: provides the container on which the txt must be present - @returns a real name object - """ - names.o_text_object["container"] = screen_obj - names.o_text_object["text"] = txt - return names.o_text_object - - -def get_bullet_object(screen_obj, num): - """ - To obtain a bullet object based on occurrence provided. - @param screen_obj: provides the container on which the bullet must be present - @param num: provides the occurrence value - @returns a real name object - """ - names.o_bullet_object["container"] = screen_obj - names.o_bullet_object["occurrence"] = num + 1 - return names.o_bullet_object - - -def get_indicators(screen_obj, txt): - """ - Verifying the busy indicators for BiCarb Pump Check and Acid Pump Check. - indicator object of expected text - @param step - (str) expected text - @return indicators - (obj) list of busy and check indicator - """ - parent_obj = object.parent(squish.waitForObjectExists(get_text_object(screen_obj,txt))) - children_obj = object.children(parent_obj) - indicator_parent = children_obj[2] - indicators = object.children(indicator_parent) - return indicators - - def verify_missing_object(object_to_check): """ Method to verify the given object is invisible or is not present on the screen @@ -186,14 +178,111 @@ test.fail("Given object should not be present initially") except LookupError as _: test.passes("object is not present as expected") - - squish.testSettings.objectNotFoundDebugging = True + squish.testSettings.objectNotFoundDebugging = True + + +def pressure_pop_up_text_obj(text): + names.o_pop_up_pressure_text_obj["text"] = text + return names.o_pop_up_pressure_text_obj + +def pressure_text_obj(text): + names.o_pressure_text_obj["text"] = text + return names.o_pressure_text_obj + +def get_current_date_and_time(date_format='%Y/%b/%d - %H:%M'): + date = datetime.now() + return str(date.strftime(date_format)) + +def vitals_reading_obj(reading): + names.o_vitals_reading["text"] = reading + return names.o_vitals_reading + + +def get_current_date_and_time(date_format='%Y/%b/%d - %H:%M'): + date = datetime.now() + return str(date.strftime(date_format)) + +def enter_keypad_value(entry): + """ + Method to enter user desired + value using keypad + @param entry: (int) User expected value + """ + test.startSection("Entering {}".format(entry)) + entry = pyStr(entry) + for value in entry: + squish.mouseClick(squish.waitForObject(keypad_input(value))) + test.endSection() + +def erase_entered_value(input_field): + """ + Method to erase the entered value + @param input_field - (obj) object of input field + """ + test.startSection("Erasing value") + input_field= squish.waitForObject(input_field) + entered_value = str(input_field.text) + for value in range(len(entered_value)+1): + utils.waitForGUI(0.1) + squish.mouseClick(squish.waitForObjectExists(names.o_back_space_key)) + test.compare(str(input_field.text), "", "Input field should be empty") + test.endSection() + +def vitals_reading_obj(reading): + names.o_vitals_reading["text"] = reading + return names.o_vitals_reading + +def keypad_input(key_value): + names.o_keypad_input["text"] = key_value + return names.o_keypad_input + + +def scroll_to_zone(zone=None, screen_object=None, direction = None): + """ + scroll to the to the value if object is hidden + @param value - (obj) value object + @param container - (obj) Container of the value + @return boolean true and false + """ + counter = 0 + while counter <= 100: + try: + counter += 1 + squish.findObject(zone) + squish.snooze(0.5) + if check_if_object_is_within_the_container(obj=zone, container=screen_object): + return True + else: + raise RuntimeError + except RuntimeError: + ScreenObj = squish.findObject(screen_object) + screenHeight = pyInt(ScreenObj.height) + screenWidth = pyInt(ScreenObj.width) + if direction is None: + squish.mouseWheel(ScreenObj, (screenWidth-100), 107, 0, -(screenHeight-460), squish.Qt.NoModifier) + else: + squish.mouseWheel(ScreenObj, (screenWidth-100), -(screenHeight-700), 0, 200, squish.Qt.NoModifier) + + raise LookupError("zone object is not in view to the user after trying 100 times") + +def get_alarm_id_obj(id): + names.o_alarm_id["text"] = id + return names.o_alarm_id + +def get_alarm_msg_obj(msg): + names.o_alarm_message["text"] = msg + return names.o_alarm_message + +def rejection_msg(text): + names.o_rejection_msg["text"] = text + return names.o_rejection_msg + def verify_page_step_indicator(screen_obj, treatment_step, treatment_screens): """ - Method to verify the Page Step indicators [the object on top of the screen which indicates the steps passed, current, remained] - @param treatment_step : indicates the Current treatment step + Method to verify the Page Step indicators [the object on top of the screen which indicates the steps passed, current, remained] + @param treatment_step : indicates the Current treatment step """ test.startSection("verification of page step indicators") @@ -225,8 +314,754 @@ test.compare(step_title.color.name, config.INCOMPLETE_COLOR) test.compare(bullet_circle_color, config.CURRENT_COLOR) test.compare(bullet_border_color, config.INCOMPLETE_COLOR) - test.endSection() + test.endSection() +def set_arterial_ranges_min_val(art_low): + """ + Method to set the Arterial range maximum value to user expected value + @param art_low - (int) user expected value + """ + test.startSection("Set Arterial range minimum value to {}".format(art_low)) + arterial_min = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_min = pyInt(arterial_min.minimum) + arterial_max = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_max = pyInt(arterial_max.maximum) + low_handler_parent = object.parent(squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery)) + low_handler_children = object.children(low_handler_parent) + low_handler = low_handler_children[-2] + width = pyInt(low_handler.width) - 8 + height = pyInt(low_handler.height)- 10 + if arterial_min == art_low: + test.passes("Arterial range minimum is already set to {}".format(art_low)) + elif arterial_min < art_low: + while arterial_min != art_low: + squish.mouseDrag(low_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_min += 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_min == arterial_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(low_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range minimum value cannot be moved beyond {}".format(arterial_min)) + break + else: + continue + elif arterial_min > art_low: + while arterial_min != art_low: + squish.mouseDrag(low_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_min -= 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_min == arterial_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(low_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range minimum value cannot be moved beyond {}".format(arterial_min)) + break + else: + continue + # arterial blood pressure low limit should be lower than the high limit by atleast 30mmHg + if arterial_min == arterial_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + test.compare(low_handler_parent.minValue, arterial_min, "Arterial range minimum value cannot be moved beyond {}".format(arterial_min)) + else: + test.compare(arterial_min, art_low, "Actual Arterial range minimum value: {} is equal to Expected value: {}".format(arterial_min, art_low)) + test.endSection() + +def set_arterial_ranges_max_val(art_high): + """ + Method to set the Arterial range maximum value to user expected value + @param art_high - (int) user expected value + """ + test.startSection("Set Arterial range maximum value to {}".format(art_high)) + arterial_max = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_max = pyInt(arterial_max.maximum) + arterial_min = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_min = pyInt(arterial_min.minimum) + high_handler_parent = object.parent(squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery)) + high_handler_children = object.children(high_handler_parent) + high_handler = high_handler_children[-1] + width = pyInt(high_handler.width) - 20 + height = pyInt(high_handler.height) - 25 + if arterial_max == art_high: + test.passes("Arterial range maximum is already set to {}".format(art_high)) + elif arterial_max < art_high: + while arterial_max != art_high: + squish.mouseDrag(high_handler, -1, height, width, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_max += 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_max == arterial_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(high_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range maximum value cannot be moved beyond {}".format(arterial_max)) + break + else: + continue + elif arterial_max > art_high: + while arterial_max != art_high: + squish.mouseDrag(high_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_max -= 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_max == arterial_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(high_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range maximum value cannot be moved beyond {}".format(arterial_max)) + break + else: + continue + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_max == arterial_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + test.compare(high_handler_parent.maxValue, arterial_max, "Arterial range maximum value cannot be moved beyond {}".format(arterial_max)) + else: + test.compare(arterial_max, art_high, "Actual Arterial range maximum value: {} is equal to Expected value: {}".format(arterial_max, art_high)) + test.endSection() +def set_venous_ranges_max_val(ven_high): + """ + Method to set the Venous range maximum value to user expected value + @param ven_high - (int) user expected value + """ + test.startSection("Set Venous range maximum value to {}".format(ven_high)) + ven_max = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Venous) + ven_max = pyInt(ven_max.maximum) + ven_min = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Venous) + ven_min = pyInt(ven_min.minimum) + high_handler_parent = object.parent(squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Venous)) + high_handler_children = object.children(high_handler_parent) + high_handler = high_handler_children[-1] + width = pyInt(high_handler.width) - 15 + height = pyInt(high_handler.height) - 10 + if ven_max == ven_high: + test.passes("Venous range maximum is already set to {}".format(ven_high)) + elif ven_max < ven_high: + while ven_max != ven_high: + squish.mouseDrag(high_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + ven_max += 10 + # venous blood pressure low limit should be lower than the high limit by at least 30mmHg + if ven_max == ven_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(high_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Venous range maximum value cannot be moved beyond {}".format(ven_max)) + break + else: + continue + elif ven_max > ven_high: + while ven_max != ven_high: + squish.mouseDrag(high_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + ven_max -= 10 + # venous blood pressure low limit should be lower than the high limit by at least 30mmHg + if ven_max == ven_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(high_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Venous range maximum value cannot be moved beyond {}".format(ven_max)) + break + else: + continue + # venous blood pressure low limit should be lower than the high limit by at least 30mmHg + if ven_max == ven_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + test.compare(high_handler_parent.maxValue, ven_max, "Venous range maximum value cannot be moved beyond {}".format(ven_max)) + else: + test.compare(ven_max, ven_high, "Actual Venous range maximum value: {} is equal to Expected value: {}".format(ven_max, ven_high)) + test.endSection() +#Methods for create custom treatment +def set_venous_ranges_min_val(ven_low): + """ + Method to set the Venous range maximum value to user expected value + @param ven_low - (int) user expected value + """ + test.startSection("set Venous range minimum value to {}".format(ven_low)) + ven_min = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Venous) + ven_min = pyInt(ven_min.minimum) + ven_max = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Venous) + ven_max = pyInt(ven_max.maximum) + low_handler_parent = object.parent(squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Venous)) + low_handler_children = object.children(low_handler_parent) + low_handler = low_handler_children[-2] + width = pyInt(low_handler.width) - 15 + height = pyInt(low_handler.height) - 10 + if ven_min == ven_low: + test.passes("Venous range minimum is already set to {}".format(ven_low)) + elif ven_min < ven_low: + while ven_min != ven_low: + squish.mouseDrag(low_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + ven_min += 10 + if ven_min == ven_max - config.BUFFER_LOW_AND_HIGH_LIMITS: # venous blood pressure low limit should be lower than the high limit by at least 30mmHg + squish.mouseDrag(low_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Venous range minimum value cannot be moved beyond {}".format(ven_min)) + break + else: + continue + elif ven_min > ven_low: + while ven_min != ven_low: + squish.mouseDrag(low_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + ven_min -= 10 + # venous blood pressure low limit should be lower than the high limit by at least 30mmHg + if ven_min == ven_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(low_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Venous range minimum value cannot be moved beyond {}".format(ven_min)) + break + else: + continue + # venous blood pressure low limit should be lower than the high limit by at least 30mmHg + if ven_min == ven_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + test.compare(low_handler_parent.minValue, ven_min, "Venous range minimum value cannot be moved beyond {}".format(ven_min)) + else: + test.compare(ven_min, ven_low, "Actual Venous range minimum value: {} is equal to Expected value: {}".format(ven_min, ven_low)) + test.endSection() + +def expected_heparin_value(val): + names.o_heparin_value["text"] = val + return names.o_heparin_value +def msg(string): + """ + Added ### at the right side of the string to make sure that it is a message. + @param string: (str) the string to add trailing ### to + @return pad_str: (str) padded string + """ + padded_str = "###"+string + return padded_str + +def navigate_to_pretreatment_screen(mode): + """ + Method to navigate to sub mode under pre-treatment screen + @param mode - (int) pre treatment state + """ + hd_simulator.cmd_set_hd_operation_mode_data(HDOpModes.MODE_PRET.value,0) + hd_simulator.cmd_send_pre_treatment_state_data(sub_mode=mode, water_sample_state=0, + consumables_self_test_state=0, no_cartridge_self_test_state=0, + installation_state=0, dry_self_test_state=0, prime_state=0, + recirculate_state=0, patient_connection_state=0) + +def self_test_dry_check_list_text(text): + names.o_self_test_dry_check_list_text["text"] = text + return names.o_self_test_dry_check_list_text + +def get_time(screen_title): + """ + Method to return the current count down + in the application + @param screen_title - (str) current title of the screen + @return time_text - (str) count down in the application + """ + if screen_title == config.BEGIN_PRIME_TITLE or screen_title == config.PRIMING_TITLE: + parent_object = object.parent(squish.waitForObjectExists(self_test_dry_check_list_text(screen_title))) + elif screen_title == config.SYSTEM_SELF_TEST_TITLE: + parent_object = object.parent(squish.waitForObjectExists(names.o_system_self_test)) + else: + parent_object = object.parent(squish.waitForObjectExists(names.o_PreTreatmentBase_Filter_Flush_Text)) + time_parent_children = object.children(parent_object) + progress_circle_parent = time_parent_children[4] + progress_circle_parent = object.children(progress_circle_parent) + progress_circle_parent = progress_circle_parent[0] + progress_circle_parent = object.children(progress_circle_parent) + progress_circle_children = object.children(progress_circle_parent[0]) + time_text = progress_circle_children[1] + return time_text.time + +def verify_countdown(screen_title, time_out, hd_simulator, dg_simulator): + """ + Method to verify the count down + time in application + @param screen_title - (str) current title of the screen + @param time_out - (int) time out duration in secs + @Param hd_simulator - Instance of class HDSimulator + @Param dg_simulator - Instance of class DGSimulator + """ + test.startSection("Verify the count down time in application") + for count_down in range(config.COUNT_DOWN_TIME_100, config.MINIMUM_COUNTDOWN_TIME-1, -1): + if screen_title == config.BEGIN_PRIME_TITLE: + hd_simulator.cmd_send_pre_treatment_self_test_dry_progress_data(time_out, count_down) + elif screen_title == config.PRIMING_TITLE: + hd_simulator.cmd_send_pre_treatment_disposables_prime_progress_data(time_out, count_down) + elif screen_title == config.SYSTEM_SELF_TEST_TITLE: + hd_simulator.cmd_send_pre_treatment_self_test_no_cartridge_progress_data(time_out, count_down) + else: + dg_simulator.cmd_send_dg_pre_treatment_filter_flush_progress_data(time_out, count_down) + actual_time = get_time(screen_title) + expected_time = convert_seconds_into_min_and_sec(count_down) + test.compare(actual_time, expected_time, "Actual count down time: {} should be equal to expected count down time {}".format(actual_time, expected_time)) + verify_the_progress(count_down, screen_title, time_out) + test.endSection() + +def verify_the_progress(count_down, screen_title, time_out): + """ + Method to verify the current progress + @param count_down - (int) current count down time + @param screen_title - (str) current title of the screen + @param time_out - (int) time out duration in secs + """ + test.startSection("Verifying the current progress") + if screen_title == config.BEGIN_PRIME_TITLE or screen_title == config.PRIMING_TITLE: + current_progress = (squish.waitForObjectExists(names.o_self_test_dry_progress)).progressValue + elif screen_title == config.SYSTEM_SELF_TEST_TITLE: + current_progress = (squish.waitForObjectExists(names.o_system_self_test_progress)).progressValue + else: + current_progress = (squish.waitForObjectExists(names.o_filter_flush_progress)).progressValue + #Since progress value is equal maximum count down value - current count down value + expected_progress = time_out - count_down + test.compare(current_progress, expected_progress, "{} should be the current progress".format(expected_progress)) + test.endSection() + +def verify_page_step_indicator(screen_obj, treatment_step, treatment_screens): + """ + Method to verify the Page Step indicators [the object on top of the screen which indicates the steps passed, current, remained] + @param treatment_step : (int) indicates the Current treatment step + """ + test.startSection("verification of page step indicators") + for page in range(len(treatment_screens)): + bullet_children = object.children(squish.waitForObjectExists(get_bullet_object(screen_obj, page))) + bullet_circle_color = bullet_children[0].color.name + bullet_border_color = bullet_children[0].border.color.name + step_title = squish.waitForObjectExists(get_text_object(screen_obj, treatment_screens[page])) + #To verify the step indicators of the completed treatment screens + if page < treatment_step: + test.verify(squish.waitForObjectExists(get_bullet_object(screen_obj, page)).complete) + test.verify(not squish.waitForObjectExists(get_bullet_object(screen_obj, page)).current) + test.compare(bullet_circle_color, config.COMPLETE_COLOR) + test.compare(bullet_border_color, config.COMPLETE_COLOR) + test.compare(step_title.color.name, config.ENABLED_COLOR) + #To verify the step indicators of the current treatment screen + elif page == treatment_step: + test.verify(squish.waitForObjectExists(get_bullet_object(screen_obj, page)).current,) + test.verify(not squish.waitForObjectExists(get_bullet_object(screen_obj, page)).complete) + test.compare(bullet_circle_color, config.CURRENT_COLOR) + test.compare(bullet_border_color, config.COMPLETE_COLOR) + test.compare(step_title.color.name, config.ENABLED_COLOR) + test.verify(step_title.font.bold) + #To verify the step indicators of the remaining treatment screens + else: + test.verify(not squish.waitForObjectExists(get_bullet_object(screen_obj, page)).current,) + test.verify(not squish.waitForObjectExists(get_bullet_object(screen_obj, page)).complete,) + test.compare(step_title.color.name, config.INCOMPLETE_COLOR) + test.compare(bullet_circle_color, config.CURRENT_COLOR) + test.compare(bullet_border_color, config.INCOMPLETE_COLOR) + test.endSection() + +def verify_missing_object(object_to_check): + """ + Method to verify the given object is invisible or is not present on the screen + @param object_to_check: the object whose invisibility must be verified + """ + try: + squish.testSettings.objectNotFoundDebugging = False + squish.waitForObject(object_to_check,3000) + test.fail("Given object should not be present initially") + except LookupError as _: + test.passes("object is not present as expected") + squish.testSettings.objectNotFoundDebugging = True + +def set_arterial_ranges_min_val(art_low): + """ + Method to set the Arterial range maximum value to user expected value + @param art_low - (int) user expected value + """ + test.startSection("Set Arterial range minimum value to {}".format(art_low)) + arterial_min = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_min = pyInt(arterial_min.minimum) + arterial_max = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_max = pyInt(arterial_max.maximum) + low_handler_parent = object.parent(squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery)) + low_handler_children = object.children(low_handler_parent) + low_handler = low_handler_children[-2] + width = pyInt(low_handler.width) - 8 + height = pyInt(low_handler.height)- 10 + if arterial_min == art_low: + test.passes("Arterial range minimum is already set to {}".format(art_low)) + elif arterial_min < art_low: + while arterial_min != art_low: + squish.mouseDrag(low_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_min += 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_min == arterial_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(low_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range minimum value cannot be moved beyond {}".format(arterial_min)) + break + else: + continue + elif arterial_min > art_low: + while arterial_min != art_low: + squish.mouseDrag(low_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_min -= 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_min == arterial_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(low_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range minimum value cannot be moved beyond {}".format(arterial_min)) + break + else: + continue + # arterial blood pressure low limit should be lower than the high limit by atleast 30mmHg + if arterial_min == arterial_max - config.BUFFER_LOW_AND_HIGH_LIMITS: + test.compare(low_handler_parent.minValue, arterial_min, "Arterial range minimum value cannot be moved beyond {}".format(arterial_min)) + else: + test.compare(arterial_min, art_low, "Actual Arterial range minimum value: {} is equal to Expected value: {}".format(arterial_min, art_low)) + test.endSection() + + +def set_arterial_ranges_max_val(art_high): + """ + Method to set the Arterial range maximum value to user expected value + @param art_high - (int) user expected value + """ + test.startSection("Set Arterial range maximum value to {}".format(art_high)) + arterial_max = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_max = pyInt(arterial_max.maximum) + arterial_min = squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery) + arterial_min = pyInt(arterial_min.minimum) + high_handler_parent = object.parent(squish.waitForObjectExists(names.o_PreTreatmentCreate_rangeRect_RangeRect_Artery)) + high_handler_children = object.children(high_handler_parent) + high_handler = high_handler_children[-1] + width = pyInt(high_handler.width) - 20 + height = pyInt(high_handler.height) - 25 + if arterial_max == art_high: + test.passes("Arterial range maximum is already set to {}".format(art_high)) + elif arterial_max < art_high: + while arterial_max != art_high: + squish.mouseDrag(high_handler, -1, height, width, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_max += 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_max == arterial_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(high_handler, width, height, 1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range maximum value cannot be moved beyond {}".format(arterial_max)) + break + else: + continue + elif arterial_max > art_high: + while arterial_max != art_high: + squish.mouseDrag(high_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + arterial_max -= 10 + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_max == arterial_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + squish.mouseDrag(high_handler, width, height, -1, 0, squish.Qt.NoModifier, squish.Qt.LeftButton) + test.log("Arterial range maximum value cannot be moved beyond {}".format(arterial_max)) + break + else: + continue + # arterial blood pressure low limit should be lower than the high limit by at least 30mmHg + if arterial_max == arterial_min + config.BUFFER_LOW_AND_HIGH_LIMITS: + test.compare(high_handler_parent.maxValue, arterial_max, "Arterial range maximum value cannot be moved beyond {}".format(arterial_max)) + else: + test.compare(arterial_max, art_high, "Actual Arterial range maximum value: {} is equal to Expected value: {}".format(arterial_max, art_high)) + test.endSection() + +def get_text_object(screen_obj, txt): + """ + To obtain a text object based on text provided + @param screen_obj: provides the container on which the txt must be present + @returns a real name object + """ + names.o_text_object["container"] = screen_obj + names.o_text_object["text"] = txt + return names.o_text_object + +def verify_color_of_entry(entry, vital_parameter, input_field): + """ + Method to verify the color of entry + of systolic, diastolic and heart rate + @param entry: (int) user user entered value + @param vital_parameter - (str) parameter name under which user is entering value (sys/dia/heart rate) + @param input_field - (obj) object of input field + """ + test.startSection("Verify the color of {} value {}".format(vital_parameter, entry)) + input_field_color = input_field.color.name + entry = pyInt(entry) + if vital_parameter is config.SYSTOLIC_TEXT: + if (entry < config.SYSTOLIC_LOWER_LIMIT) or (entry > config.SYSTOLIC_UPPER_LIMIT): + test.compare(input_field_color, config.OUT_OF_RANGE_COLOR, "systolic value {} is out of range, systolic value should be in range of {} and {}".format(entry, config.SYSTOLIC_LOWER_LIMIT, config.SYSTOLIC_UPPER_LIMIT)) + elif (entry >= config.SYSTOLIC_LOWER_LIMIT) and (entry <= config.SYSTOLIC_UPPER_LIMIT): + test.compare(input_field_color, config.IN_RANGE_COLOR, "systolic value {} is in range of {} and {}".format(entry, config.SYSTOLIC_LOWER_LIMIT, config.SYSTOLIC_UPPER_LIMIT)) + elif vital_parameter is config.DIASTOLIC_TEXT: + if (entry < config.DIASTOLIC_LOWER_LIMIT) or (entry > config.DIASTOLIC_UPPER_LIMIT): + test.compare(input_field_color, config.OUT_OF_RANGE_COLOR, "diastolic value {} is out of range, diastolic value should be in range of {} and {}".format(entry, config.DIASTOLIC_LOWER_LIMIT, config.DIASTOLIC_UPPER_LIMIT)) + elif (entry >= config.DIASTOLIC_LOWER_LIMIT) and (entry <= config.DIASTOLIC_UPPER_LIMIT): + test.compare(input_field_color, config.IN_RANGE_COLOR, "diastolic value {} is in range of {} and {}".format(entry, config.DIASTOLIC_LOWER_LIMIT, config.DIASTOLIC_UPPER_LIMIT)) + elif vital_parameter is config.HEART_RATE_TITLE: + if (entry < config.HEART_RATE_LOWER_LIMIT) or (entry > config.HEART_RATE_UPPER_LIMIT): + test.compare(input_field_color, config.OUT_OF_RANGE_COLOR, "Heart Rate value {} is out of range, Heart Rate value should be in range of {} and {}".format(entry, config.HEART_RATE_LOWER_LIMIT, config.HEART_RATE_UPPER_LIMIT)) + elif (entry >= config.HEART_RATE_LOWER_LIMIT) and (entry <= config.HEART_RATE_UPPER_LIMIT): + test.compare(input_field_color, config.IN_RANGE_COLOR, "Heart Rate value {} is in range of {} and {}".format(entry, config.HEART_RATE_LOWER_LIMIT, config.HEART_RATE_UPPER_LIMIT)) + test.endSection() + +def keypad_input(key_value): + """ + Method to enter values using application UI keyboard + @param key_value: (str) User expected value + """ + if key_value is not None: + names.o_keypad_input["text"] = key_value + return names.o_keypad_input + else: + test.log("Invalid text for object.") + names.o_keypad_input["text"] = None + +def enter_keypad_value(entry): + """ + Method to enter user desired + value using keypad + @param entry: (str) User expected value + """ + test.startSection("Entering {}".format(entry)) + entry = pyStr(entry) #type casted into string format + for value in entry: + squish.mouseClick(squish.waitForObject(keypad_input(value))) + test.endSection() + +def is_float(num): + """ + This function checks the value is adaptable for float conversion. + @param num - (string) input value for conversion. + @return True/False- (bool) returns True if the value can type casted into float, else False + """ + try: + if '.' in num: + float(num) + return True + except ValueError: + return False + +def is_intiger(num): + """ + This function checks the value is adaptable for integer conversion. + @param num - (string) (string) input value for conversion. + @return True/False- (bool) returns True if the value can type casted into int, else False + """ + try: + if num.isdigit(): + return True + except ValueError: + return False + +def get_extracted_file(): + """ + This function is the handler for getting file from log folder. + This handler will go inside log folder and looks for newly added log based on current time. + if it satisfied that condition, it will return the exact path of newly created log. + Application log file is automatically created on '/home/denali/Desktop/sd-card/log/ {current_date}_denaliSquish.log' + @return latest_file - (string) returns latest file that append on log folder from sd-data + """ + try: + current_date = get_current_date_and_time(date_format = "%Y_%m_%d") + latest_file = '/home/denali/Desktop/sd-card/log/'+current_date+'_denaliSquish.log' + return latest_file + except: + return False + +def get_message_from_log(file_name, message_text): + + """ + This method intended to extract the message from application log. + For row[index], index represent column to be extracted. + @param file_name - (string) path of the latest log file created. + @param message_text - (string) message text to be extracted. + @return message - (list) API arguments displayed in log. + """ + message = [] + count = 0 + try: + with open(file_name, 'r') as csv_file: + try: + for row in reversed(list(csv.reader(csv_file))): + if row[0].isalpha(): + pass + else: + row_length = sum(1 for values in row) + if row_length >= 4: + if row[3]!= None and row[3] == message_text: + if count == 30: + test.fail("handler unable to find message text from log file.") + message_length = sum(1 for values in row) + for column in range(4, message_length, 1): + message.append(row[column]) + count +=1 + for value in range(len(message)): + float_status = is_float(message[value]) + int_status = is_intiger(message[value]) + if float_status is True: + message[value] = float(message[value]) + if int_status is True: + message[value] = int(message[value]) + test.log(str(message)) + return message + else: + pass + except: + test.fail("application log data is corrupted") + except: + test.fail("Log file is not created or log file is not created based on standard log naming format.") + +def get_ack_request_details(file_name, message_text): + """ + This method intended to extract acknowledgement request status, negative requested acknowledgement + and message id from application log. + For row[index], were index represent column to be extracted. + @param file_name - (string) path of the latest log file created. + @param message_text - (string) message text to be extracted from log. + @return row[3] - (string) acknowledgement request status. + @return row[4] - (string) Negative requested acknowledgement value (Sq). + @return message_id - (string) formatted message id from log. + """ + try: + message_id = " ID" + with open(file_name, 'r') as csv_file: + try: + for row in reversed(list(csv.reader(csv_file))): + if row[0].isalpha(): + pass + else: + row_length = sum(1 for values in row) + if row_length == 6 and row[3] != message_text: + if row[5].split(':')[0] == message_id: + extracted_message_id = pyInt(row[5].split(':')[1], 16) + formatted_message_id = format(extracted_message_id, '#0x') + # MSG_ID_HD_DEBUG_EVENT (0xFFF1) and MSG_ID_DG_DEBUG_EVENT (0xFFF2) hex values are reversed in log. + string_format_id = str(formatted_message_id) + first_two_char = string_format_id[2:4] + last_two_char = string_format_id[-2:] + if last_two_char != '00': + return row[3], row[4], ('0x'+last_two_char+first_two_char) + else: + return row[3], row[4], formatted_message_id.replace("00", "") + else: + pass + except: + test.fail("application log data is corrupted - unable to fetch data") + except: + test.fail("Log file is not created or log file is not created based on standard log naming format.") + +def get_bak_request_details(file_name, ack_bak_value): + """ + This method intended to extract the acknowledgement back status from application log. + For row[index], were index represent column to be extracted. + @param file_name - (string) path of the latest log file created. + @param ack_bak_value - (string) Positive back acknowledgement value (Sq). + @return row[3] - (string) acknowledgement back status. + """ + try: + with open(file_name, 'r') as csv_file: + try: + for row in reversed(list(csv.reader(csv_file))): + if row[0].isalpha(): + pass + else: + row_length = sum(1 for values in row) + if row_length >= 5: + if row[4] == ack_bak_value: + return row[3] + else: + pass + else: + pass + except: + test.fail("application log data is corrupted") + except: + test.fail("Log file is not created or log file is not created based on standard log naming format.") + +def get_current_log_details(message_ack = False, message_text = None): + """ + This function is capable to perform data analysis from application log folder. + logs are automatically created in path :"/home/denali/Desktop/sd-card/log/*.log". + In row[index], index represent column to be extracted. + @param message_ack - (bool) 'True' - if ack is satisfied in log / 'False' - if ack condition is not satisfied + @param message_text - (string) message text to be extracted from log. + @return content_record - (list) list contains extracted data (ack_req, ack_bak, message, message_id). + """ + content_record = [] + file_name = get_extracted_file() + if message_text != None: + message = get_message_from_log(file_name, message_text) + content_record.append(message) + if message_ack != False: + ack_req_status, ack_req_value, message_id = get_ack_request_details(file_name, message_text) + ack_bak_value = ack_req_value.replace(":-", ":") # getting negative requested ack from positive requested ack + content_record.append(ack_req_status) + content_record.append(message_id.lower()) + if message_ack != False and ack_bak_value != None: + ack_bak_status = get_bak_request_details(file_name, ack_bak_value) + content_record.append(ack_bak_status) + return content_record + +def vitals_interval_obj(interval): + names.o_time_interval_obj["text"] = interval + return names.o_time_interval_obj + +def get_extracted_error_file(): + """ + This function is the handler for getting error file from service folder. + Application log file is automatically created on '/home/denali/Desktop/sd-card/service/ {current_date}_denaliSquish.err ' + @return latest_file - (string) returns latest file that append on log folder from service + """ + try: + current_date = get_current_date_and_time(date_format = "%Y_%m_%d") + latest_file = '/home/denali/Desktop/sd-card/service/'+current_date+'_denaliSquish.err' + return latest_file + except: + return False + +def keyboard_input(key_value): + names.o_keyboard_object["text"] = key_value + return names.o_keyboard_object + +def enter_keyboard_numeric_value(entry): + """ + Method to enter user desired + value using keypad + @param entry: (str) User expected value + """ + test.startSection("Entering {}".format(entry)) + for value in entry: + if value.isalpha(): + value = pyStr(value) + else: + value = pyInt(value) + key_val = squish.waitForObject(keyboard_input(value)) + squish.mouseClick(key_val) + utils.waitForGUI(0.1) + test.endSection() + + +def end_treatment_states_rejection_msg(text): + names.o_end_treatment_state_rejection_msg["text"] = text + return names.o_end_treatment_state_rejection_msg + +def verify_parameter_from_post_treatment_log(msg_text): + """ + To obtain the details of parameter from post treatment log file. + @param msg_text: parameter to be extracted. + @returns message value and message unit + """ + try: + log_location = str(get_extracted_file_from_post_treatment()) + with open(log_location, 'r') as csv_file: + try: + for row in csv_file: + reader = csv.reader(csv_file) + for row in reader: + row_length = sum(1 for values in row) + for row1 in row: + if row[0]!= None and row[0] == msg_text and row_length == 3: + return (row[1],row[2]) + else: + pass + except: + test.fail("Treatment log data is corrupted") + except: + test.fail("Log file is not created or log file is not created based on standard log naming format.") + +def get_extracted_file_from_post_treatment(): + """ + This function is the handler for getting file from log folder. + This handler will go inside log folder and looks for newly added log based on current time. + if it satisfied that condition, it will return the exact path of newly created log. + @return latest_file - (string) returns latest file that append on log folder from sd-data + """ + try: + list_of_files = glob.glob(config.TREATMENT_LOG_LOCATION) + latest_file = max(list_of_files, key=os.path.getctime) + return latest_file + except: + test.fail("log file is not created during application interaction") + return False + + +def rinseback_rejection_msg(text): + names.o_rinseback_rejection_msg["text"] = text + return names.o_rinseback_rejection_msg + squish.testSettings.objectNotFoundDebugging = True + + +def recirculate_rejection_msg(text): + names.o_recirculate_rejection_msg["text"] = text + return names.o_recirculate_rejection_msg + + Index: shared/scripts/names.py =================================================================== diff -u -r11b2970e98eb80e8bd299d25b607b8ff00a2043b -rde4dd0bb518628a7cdb691f5af71f8d2ffa02d52 --- shared/scripts/names.py (.../names.py) (revision 11b2970e98eb80e8bd299d25b607b8ff00a2043b) +++ shared/scripts/names.py (.../names.py) (revision de4dd0bb518628a7cdb691f5af71f8d2ffa02d52) @@ -768,12 +768,16 @@ o_disposables_removal_right_arrow = {"container": o_PostTreatmentStack_disposablesRemovalConfirm_TreatmentFlowBase, "id": "_rightImage", "source": "qrc:/images/iArrowRight", "type": "Image", "unnamed": 1, "visible": True} o_disposables_removal_text = {"container": o_PostTreatmentStack_disposablesRemovalConfirm_TreatmentFlowBase, "text": "Disposables Removal", "type": "Text", "unnamed": 1, "visible": True} o_treatmentReviewConfirm_Export_Text = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "text": "Export", "type": "Text", "unnamed": 1, "visible": True} +o_eject_button = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "id": "_image", "source": "qrc:/images/iEject", "type": "Image", "unnamed": 1, "visible": True} +o_right_arrow = {"id": "_rightImage", "source": "qrc:/images/iArrowRight", "type": "Image", "unnamed": 1, "visible": True} o_left_arrow = {"id": "_leftImage", "source": "qrc:/images/iArrowLeft", "type": "Image", "unnamed": 1, "visible": True} #post treatment review o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview_ONE = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "type": "Text", "unnamed": 1, "visible": True} o_review_area = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "id": "_flickable", "type": "Flickable", "unnamed": 1, "visible": True} o_review_text = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "type": "Text", "unnamed": 1, "visible": True} +o_code_text = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "text": "Code: ", "type": "Label", "unnamed": 1, "visible": True} +o_code_text_after_passing_log_values = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "text": "Code: ...", "type": "Label", "unnamed": 1, "visible": True} #patient ID from create custom treatment o_treatmentReviewConfirm_NEXT_Text = {"container": o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview, "text": "NEXT", "type": "Text", "unnamed": 1, "visible": True} Index: tst_post_treatment/test.py =================================================================== diff -u -r4a39e403e4b0e1a7a9d4056230528a187cbc44ee -rde4dd0bb518628a7cdb691f5af71f8d2ffa02d52 --- tst_post_treatment/test.py (.../test.py) (revision 4a39e403e4b0e1a7a9d4056230528a187cbc44ee) +++ tst_post_treatment/test.py (.../test.py) (revision de4dd0bb518628a7cdb691f5af71f8d2ffa02d52) @@ -11,16 +11,15 @@ # date 2022/05/20 # author Joseph Varghese # author Akshay Dhawan -# author Shweta POlicepatil +# author Shweta Policepatil # author Amol Shinde # NOTE: # This test contradicts verification of post treatment section. -import builtins + import names import csv import test -import time import builtins from dialin.ui import utils from datetime import * @@ -31,16 +30,10 @@ hd_simulator = HDSimulator() -NUM_OF_POSTTREATMENT_BULLETS = len(config.POST_TREATMENT_SCREENS) + SCREEN_OBJ1 = names.o_PostTreatmentStack_patientDisconnectionConfirm_TreatmentFlowBase -SCREEN_OBJ2 = names.o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview SCREEN_OBJ3 = names.o_PostTreatmentStack_disposablesRemovalConfirm_TreatmentFlowBase num_of_instructionss = 0 -NUM_OF_PATIENT_DISCONNECTION_SCREENS = 2 -NUM_OF_DISPOSABLE_INSTALLATION_SCREENS = 7 -DISPOSABLES_STEP = 2 -PATIENT_DISCONNECTION_STEP = 0 -REVIEW_TREATMENT_STEP = 1 rightarrow_obj_names = [names.o_PostTreatmentStack_patientDisconnectionConfirm_TreatmentFlowBase] leftarrow_obj_names = [names.o_PostTreatmentStack_patientDisconnectionConfirm_TreatmentFlowBase] @@ -169,6 +162,7 @@ """ test.startSection("instruction bullet verification for screens") for instruction in range(1, num_of_instructions): + NUM_OF_POSTTREATMENT_BULLETS = len(config.POST_TREATMENT_SCREENS) bullet_children = object.children(waitForObjectExists(utility.get_bullet_object(screen_obj,(NUM_OF_POSTTREATMENT_BULLETS + instruction) - 1))) bullet_circle_color = bullet_children[0].color.name bullet_border_color = bullet_children[0].border.color.name @@ -188,7 +182,9 @@ Method to verify parameters under 'Patient Disconnection Screens' """ test.startSection("verifying Patient Disconnection screen") + PATIENT_DISCONNECTION_STEP = 0 utility.verify_page_step_indicator(SCREEN_OBJ1, PATIENT_DISCONNECTION_STEP, config.POST_TREATMENT_SCREENS) + NUM_OF_PATIENT_DISCONNECTION_SCREENS = 2 verify_right_instruction_navigation_patient_disconnection(NUM_OF_PATIENT_DISCONNECTION_SCREENS) verify_left_instruction_navigation_patient_disconnection(NUM_OF_PATIENT_DISCONNECTION_SCREENS) verify_right_instruction_navigation_patient_disconnection(NUM_OF_PATIENT_DISCONNECTION_SCREENS) @@ -203,10 +199,15 @@ Method to verify parameters under 'Treatment Review Screens' """ test.startSection("Verifying Treatment Review Screen") + SCREEN_OBJ2 = names.o_PostTreatmentStack_treatmentReviewConfirm_PostTreatmentReview + REVIEW_TREATMENT_STEP = 1 utility.verify_page_step_indicator(SCREEN_OBJ2, REVIEW_TREATMENT_STEP, config.POST_TREATMENT_SCREENS) - test.compare(waitForObject(names.o_treatment_review_next_text).text, config.NEXT_TEXT, "NEXT button text must be NEXT") - test.verify(not waitForObjectExists(names.o_treatmentReviewConfirm_Export_Text).enabled, " Export button should not be active") + test.verify(waitForObjectExists(names.o_treatmentReviewConfirm_Export_Text).enabled, " Export button should be enabled") test.compare(str(waitForObjectExists(names.o_treatmentReviewConfirm_Export_Text).text), config.EXPORT_TEXT,"Export button text must be {}".format(config.EXPORT_TEXT)) + test.verify(waitForObjectExists(names.o_treatmentReviewConfirm_Export_Text).enabled, " Export button should be enabled") + test.verify(waitForObject(names.o_eject_button).enabled, "Eject button must be enable") + mouseClick(waitForObject(names.o_eject_button)) + test.verify(not waitForObjectExists(names.o_treatmentReviewConfirm_Export_Text).enabled, " Export button should be disabled") verify_post_treatment_review_parameters() verify_post_treatment_review_log_data() test.verify(waitForObject(names.o_treatment_review_next_button).enabled, "NEXT button must be enabled") @@ -223,8 +224,10 @@ mouseClick(waitForObjectExists(names.o_disposablesRemovalConfirm_BACK_Text)) utils.waitForGUI(0.3) #Delay given for screen navigation mouseClick(waitForObject(names.o_treatment_review_next_button)) + DISPOSABLES_STEP = 2 utility.verify_page_step_indicator(SCREEN_OBJ3, DISPOSABLES_STEP, config.POST_TREATMENT_SCREENS) names.o_bullet_object.pop("occurrence") + NUM_OF_DISPOSABLE_INSTALLATION_SCREENS = 6 verify_right_instruction_navigation_disposables(NUM_OF_DISPOSABLE_INSTALLATION_SCREENS) test.verify(waitForObjectExists(names.o_disposables_removal_confirm_button).enabled, " confirm button must be active") verify_left_instruction_navigation_disposables(NUM_OF_DISPOSABLE_INSTALLATION_SCREENS) @@ -242,6 +245,7 @@ test.startSection("verification of post treatment review parameters with Units") treatment_review_text = waitForObjectExists(post_treatment_review_text_obj(config.TREATMENT_REVIEW_TITLE_TEXT)) test.compare(treatment_review_text.text, config.TREATMENT_REVIEW_TITLE_TEXT, "{} screen is displayed".format(config.TREATMENT_REVIEW_TITLE_TEXT)) + test.compare(str(waitForObjectExists(names.o_code_text).text), config.CODE_TEXT, "Code text must be {}".format(config.CODE_TEXT)) utils.waitForGUI(0.1) for parameter in config.POST_TREATMENT_REVIEW_SCREEN_UNITS.keys(): utility.scroll_to_zone(review_text(parameter), names.o_review_area) @@ -260,7 +264,7 @@ Method to fetch patient ID from create custom treatment in post treatment review """ test.startSection("Method for navigate to create custom treatment to set all parameters ") - hd_simulator.cmd_send_hd_operation_mode(op_mode = HDOpModes.MODE_TPAR.value , sub_mode = HDOpSubModes.SUBMODE_START.value) + hd_simulator.cmd_send_hd_operation_mode(op_mode=HDOpModes.MODE_TPAR.value, sub_mode = HDOpSubModes.STANDBY_START_STATE.value) mouseClick(waitForObject(names.o_input_patient_id)) type(waitForObject(names.o_input_patient_id), patient_id) mouseClick(waitForObject(names.o_confirm_button)) @@ -303,7 +307,7 @@ treatment_end_date_time = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Treatment End DateTime"][index], actual_treatment_duration = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Actual Treatment Duration"][index], dialysate_volume_used = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Dialysate Volume Used"][index], - origin_uf_volume = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Actual UF Volume"][index], + origin_uf_volume = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Prescribed UF Volume"][index], target_uf_volume = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Target UF Volume"][index], actual_uf_volume = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Actual UF Volume"][index], saline_bolus_volume = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Saline Bolus Volume"][index], @@ -319,14 +323,34 @@ average_venous_pressure = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE["Average Venous Pressure"][index] ) utils.waitForGUI(1) - + test.compare(str(waitForObjectExists(names.o_code_text_after_passing_log_values).text), config.CODE_TEXT_AFTER_LOGGING, "Code text must be {}".format(config.CODE_TEXT_AFTER_LOGGING)) + test.startSection("verification of post treatment review values for iteration -> "+str(index+1)) test.log("###verification of post treatment UI data based on config data") + for parameters_value in config.POST_TREATMENT_REVIEW_PARAMETER_RANGE.keys(): parameter_set = config.POST_TREATMENT_REVIEW_PARAMETER_RANGE[parameters_value] + #TODO: Following six parameters are not available on UI but API command is requiring this argument for logging. + if parameters_value == "Device ID": + continue + + elif parameters_value == "Average Blood Flow": + continue - if parameters_value == "Prescribed UF Rate": - review_parameter_value = review_text(text = "Average Venous Pressure") + elif parameters_value == "Average Dialysate Flow": + continue + + elif parameters_value == "Average Dialysate Temp": + continue + + elif parameters_value == "Average Arterial Pressure": + continue + + elif parameters_value == "Average Venous Pressure": + continue + + elif parameters_value == "Prescribed UF Rate": + review_parameter_value = review_text(text = "Prescribed UF Rate") utility.scroll_to_zone(zone = review_parameter_value, screen_object = names.o_review_area) elif parameters_value == "Heparin Type": @@ -344,10 +368,10 @@ continue elif parameters_value == "Acid ConcentrateType": - review_parameter_value = review_text(text = config.ACID_CONCENTRATE_POST[index]) + review_parameter_value = review_text(text = config.ACID_CONCENTRATE[index]) parameter_text = waitForObject(review_parameter_value) test.log("verification of values for parameter ->" + parameters_value) - test.compare(config.ACID_CONCENTRATE_POST[index], parameter_text.text, "parameter value should be "+str(parameter_set[index])) + test.compare(config.ACID_CONCENTRATE[index], parameter_text.text, "parameter value should be "+str(parameter_set[index])) continue elif parameters_value == "Dialyzer Type": @@ -437,7 +461,7 @@ def main(): - #TODO: Export functionality need to be verified in new build + utils.tstStart(__file__) startApplication(config.AUT_NAME) hd_simulator.cmd_send_hd_operation_mode(op_mode=HDOpModes.MODE_POST.value, sub_mode=PostTreatmentStates.HD_POST_TREATMENT_PATIENT_DISCONNECTION_STATE.value)