class CurrentHealthForm(): def __init__(self, driver, expectedValues=None): self.driver = driver self.util = UtilityFunctions(self.driver) self.load(expectedValues) def load(self, expectedValues): WDW(self.driver, 10).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.form = self.driver.find_elements_by_tag_name('form')[-1] inputs = self.form.find_elements_by_tag_name('input') self.question_elements = self.form.find_elements_by_class_name('custom-current-health') self.questions = [] for i, question in enumerate(self.question_elements): self.load_question(self.question_elements[i]) tooltips = self.form.find_elements_by_tag_name('img') self.blood_pressure_tooltip = tooltips[0] self.blood_clot_tooltip = tooltips[1] self.neuropathy_tooltip = tooltips[2] self.continue_button = self.form.find_element_by_class_name('submitForm') self.validate(expectedValues) return True def load_question(self, container): # Load question title (label), value, and any secondary questions and their values labels = container.find_elements_by_tag_name('label') question_label = self.util.get_text(labels[0]) value = None secondaryQuestions = [] # Value: None if not set options = ['yes', 'no', 'dont know'] for i, label in enumerate(labels): if i > 0 and i < 4: classes = label.get_attribute('class') if 'active' in classes: value = options[i - 1] # Find secondary questions if value == 'yes': secondary_container = container.find_element_by_class_name('custom-history_label') secondary_questions = container.find_elements_by_class_name('form-check') for secondary_question in secondary_questions: secondary_label = self.util.get_text(secondary_question) secondary_input = secondary_question.find_element_by_tag_name('input') selected = secondary_input.is_selected() secondaryQuestions.append({secondary_label: selected}) question = { 'name': question_label, # name: Kidney Conditions 'value': value, # value: 'yes' 'secondaryQuestions': secondaryQuestions, # secondaryQuesitons: [ } # {'Mild kidney problems (renal impairment)': False}, self.questions.append(question) # {'Severe kidney problems or on dialysis': False},] def validate(self, expectedValues): failures = [] if expectedValues: # meta validation try: meta_validators = expectedValues['meta'] for key, value in meta_validators.iteritems(): if key == 'num_questions' and value != len(self.questions): failures.append('CurrentHealthForm Meta: Expected ' + str(value) + ' questions. Form has ' + str(len(self.questions))) except KeyError: # No meta validation pass # Form validation # expectedValues should be dictionary containing {'questions': []} expectedQuestions = None try: expectedQuestions = expectedValues['questions'] except KeyError: # No form validation pass if expectedQuestions: # Check # of questions match if len(expectedQuestions) != len(self.questions): failures.append('CurrentHealthForm: Expecting ' + str(len(expectedQuestions)) + ' questions. Loaded ' + str(len(self.questions))) else: # Each key in each expectedQuestion (secondaryQuestions, name, value) should exist in loadedQuestion and match it's value for i, expectedQuestion in enumerate(expectedQuestions): loadedQuestion = self.questions[i] # print('comparing ' + str(i) + ': ' + str(expectedQuestion)) # print('with ' + str(loadedQuestion)) # raw_input('?') for key, expectedValue in expectedQuestion.iteritems(): try: if loadedQuestion[key] != expectedValue: failures.append('CurrentHealthForm: Question ' + str(i) + ' expected value "' + expectedValue + '". Loaded "' + loadedQuestion[key] + '"') except (TypeError, KeyError) as e: # raw_input(str(self.questions[i])) failures.append('CurrentHealthForm: Expected Key "' + key + '". Not found in question ' + str(i)) if len(failures) > 0: for failure in failures: print(failure) raise NoSuchElementException('Failed to load CurrentHealthForm') def submit(self, questionInfo, action): try: questionInfo = questionInfo['questions'] except KeyError: pass results = [] for i, question in enumerate(questionInfo): print('answering question: ' + str(i)) results.append(self.answer_question(i, question)) if action == 'submit': self.continue_button.click() return True def answer_question(self, index, questionInfo): container = self.question_elements[index] labels = container.find_elements_by_tag_name('label') question_label = self.util.get_text(labels[0]) labelIndex = {'yes': 1, 'no': 2, 'dont know': 3} # If right question, set value if question_label == questionInfo['name']: i = labelIndex[questionInfo['value']] labels[i].click() # Handle setting any secondary questions if questionInfo['value'] == 'yes' and questionInfo['secondaryQuestions']: expectedSecondaryInfo = questionInfo['secondaryQuestions'] secondary_container = container.find_element_by_class_name('custom-history_label') secondary_questions = container.find_elements_by_class_name('form-check') # Check # of secondary questions if len(secondary_questions) != len(questionInfo['secondaryQuestions']): print('CurrentHealth question "' + str(index) + '" expects ' + str(len(questionInfo['secondaryQuestions'])) + '. Loaded ' + str(len(secondary_questions))) return False # Set value for each secondary question for i, question in enumerate(secondary_questions): question_name = self.util.get_text(question) input_el = question.find_element_by_tag_name('input') print(input_el) if input_el.is_selected() != expectedSecondaryInfo[i][question_name]: self.util.click_radio(input_el) # else: # print(str(index) + ' already has correct value') else: print('Index "' + str(index) + '": Expecting ' + question_label + ' to equal ' + questionInfo['name']) return False return True def tooltip(self): p = self.form.find_elements_by_class_name('tooltip-p') self.blood_pressure_tooltip.click() if self.util.get_text(p[0]).lower() != 'blood pressure is the pressure exerted on walls of the blood vessels by circulating blood. along with body temperature, respiratory rate, and pulse rate, blood pressure is one of the four main vital signs monitored by medical professionals.': print('tooltip not clicked correctly:' + str(self.util.get_text(p[0]).lower())) return False self.blood_clot_tooltip.click() if self.util.get_text(p[1]).lower() != 'deep vein thrombosis (dvt) occurs when a blood clot (thrombus) forms in one or more of the deep veins in your body, usually in your legs. deep vein thrombosis can cause leg pain or swelling, but also can occur with no symptoms.': print('tooltip not clicked correctly:' + str(self.util.get_text(p[1]).lower())) return False self.neuropathy_tooltip.click() if self.util.get_text(p[2]).lower() != 'neuropathy is gradual onset of numbness, prickling or tingling in your feet or hands, which can spread upward into your legs and arms.': print('tooltip not clicked correctly:' + str(self.util.get_text(p[2]).lower())) return False return True
class EditTreatmentPopup(): def __init__(self, driver): self.driver = driver self.util = UtilityFunctions(self.driver) def load(self, expectedValues=None): WDW(self.driver, 10).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.container = self.driver.find_element_by_class_name('editroll') # Should only 1 on T&O view self.buttons = self.container.find_elements_by_class_name('green-hvr-bounce-to-top') return self.validate(expectedValues) def validate(self, expectedValues): self.failures = [] # Basic validation if len(self.buttons) != 2: self.failures.append('editTreatmentPopup: Expected 2 buttons, loaded ' + str(len(self.buttons))) if self.util.get_text(self.buttons[0]) != 'CANCEL': self.failures.append('editTreatmentPopup: Unexpected text on cancel button: ' + self.util.get_text(self.buttons[0])) if self.util.get_text(self.buttons[1]) != 'SAVE': self.failures.append('editTreatmentPopup: Unexpected text on save button: ' + self.util.get_text(self.buttons[1])) if expectedValues: print('editTreatmentPopup: Need to validate expectedValues') if len(self.failures) > 0: for failure in self.failures: print(failure) return False return True def parse_select_all(self, questionInfo, questionCont): done = False count = 0 while not done and count < 5: try: # Select options in specified in optionInfo # De-selecting options not contained in optionInfo name_checker = ['Severity of the side effects', 'Cost of the treatment', 'Too much travel'] radios = questionCont.find_elements_by_class_name('radio') suboption_filter = [] # Add index of any suboptions radio buttons to this list. Skip over them for i, radio in enumerate(radios): if i not in suboption_filter: inputs = radio.find_elements_by_tag_name('input') spans = radio.find_elements_by_tag_name('span') if len(inputs) == 0: print('EditTreatmentForm: radio option has no inputElements?') elif len(spans) == 0: print('EditTreatmentForm: radio option has no spanElements?') optionName = self.util.get_text(spans[0]) print('optionName: ' + optionName) optionInput = inputs[0] optionInfo = questionInfo.get(optionName, False) # raw_input('optionInfo: ' + str(optionInfo)) subOptions = False if optionInfo != False: # select input, enter comment, check for subquestions if not optionInput.is_selected(): self.util.click_radio(optionInput) self.util.set_input(radio, optionInfo.get('comment', '')) # Check for suboptions or select-all subOptions = optionInfo.get('options', False) if not subOptions: subOptions = optionInfo.get('select-all', False) else: # De-select, clear comment, update inputs (might have hidden subquestions) if optionInput.is_selected(): self.util.click_radio(optionInput) self.util.set_input(radio, '') inputs = radio.find_elements_by_tag_name('input') # Don't iterate over suboptions if len(inputs) > 1: for inputIndex, inputEl in enumerate(inputs): if inputIndex > 0: print('skipping ' + str(i + inputIndex)) suboption_filter.append(i + inputIndex) if subOptions: self.parse_select_all(subOptions, radio) done = True except StaleElementReferenceException: print('failed to parse select-all: ' + str(count)) count += 1 time.sleep(.2) if count == 5: print('EditTreatmentPopup: failed to parse select-all') def parse_complex(self, complexInfo, questionCont): # For questions w/ multiple sections (sideEffects, chemotherapy drugs, medications added/removed) # Loop through complexInfo and select given options for each category # De-select options not contained in complexInfo # Wait for categories to show up categories = None loaded = False count = 0 while not loaded and count < 5: # Doesn't immediately load categories = questionCont.find_elements_by_class_name('col-md-6') if categories: loaded = True else: time.sleep(.2) count += 1 question = {} for i, category in enumerate(categories): # Has issues loading category name sometimes. # Make sure it's loaded before looking for options loadedCategoryName = False count = 0 while not loadedCategoryName and count < 5: try: categoryName = self.util.get_text(category.find_element_by_class_name('treatment-group')) loadedCategoryName = True except NoSuchElementException: categoryName = None if categoryName: # Loaded name! Parse through category options categoryOptions = complexInfo.get(categoryName, False) options = {} for radio in category.find_elements_by_class_name('radio'): inputs = radio.find_elements_by_tag_name('input') labels = radio.find_elements_by_tag_name('label') label = labels[0] optionName = self.util.get_text(label) optionInput = label.find_element_by_tag_name('input') optionInfo = False if categoryOptions: optionInfo = categoryOptions.get(optionName, False) if optionInfo != False: # select input, enter comment/intensity if not optionInput.is_selected(): self.util.click_radio(optionInput) self.util.set_input(radio, optionInfo.get('comment', '')) self.set_intensity(radio, optionInfo.get('intensity', None)) else: # De-select, clear comment, update inputs (might have hidden subquestions) if optionInput.is_selected(): self.util.click_radio(optionInput) self.util.set_input(radio, '') inputs = radio.find_elements_by_tag_name('input') else: # Failed to find categoryName count += 1 time.sleep(.2) if complexInfo.get('date', None): print('complex question has date. Need to set it') def set_intensity(self, container, value): try: sliderEl = container.find_element_by_class_name('rc-slider-handle') except NoSuchElementException: print('SideEffectsForm: failed to load sliderEl') curValue = sliderEl.get_attribute('aria-valuenow') # Need to change intensity value? if value != curValue: xOffset = None # Every time offset doesn't work, increase by 5 and try again additionalOffset = 0 while str(curValue) != str(value) and additionalOffset < 50: if curValue != 1: # reset to base position AC(self.driver).drag_and_drop_by_offset(sliderEl, -200, 0).perform() # Calculate offset # Note: monitor and window sizes affect this. if xOffset != None: # First offset wasn't correct. Increment amount of offset additionalOffset += 4 xOffset = 11*(value - 1) + additionalOffset AC(self.driver).drag_and_drop_by_offset(sliderEl, xOffset, 0).perform() curValue = sliderEl.get_attribute('aria-valuenow') def set_input(self, container, value): # Return if able to set value into textarea or input in container. try: textareaEl = container.find_element_by_tag_name('textarea') textareaEl.clear() textareaEl.send_keys(value) return True except NoSuchElementException: try: inputEl = container.find_element_by_tag_name('input') if inputEl.get_attribute('type') == 'text': inputEl.clear() inputEl.send_keys(value) return True except NoSuchElementException: return False def edit_treatment(self, newInfo, popupType, action='save'): # Submit info if popupType == 'side effects': self.parse_complex(newInfo['options'], self.container) elif popupType == 'outcomes': self.parse_select_all(newInfo['options'], self.container) # Save or cancel if action == 'save': self.util.click_el(self.buttons[1]) elif action == 'cancel': self.util.click_el(self.buttons[0]) WDW(self.driver, 15).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) return True