def load(self, expectedValues=None, expectedState=None): try: WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.util = UtilityFunctions(self.driver) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) self.state = self.load_state() if expectedState and expectedState != self.state: print('Wrong state! Expected ' + str(expectedState) + ', got ' + str(self.state)) return False if self.state == 'fresh': self.newAccountPopUpForm = newAccountPopUpForm.NewAccountPopUpForm( self.driver) # load new popup # todo: need new account to get this state pass else: try: # Only shows up when certain diagnoses are selected on 'Myeloma Diagnosis' self.view_options_button = self.driver.find_element_by_class_name( 'treatment_op_btn') except NoSuchElementException: self.view_options_button = None self.load_add_treatment_button() self.saved_tests = self.driver.find_elements_by_class_name( 'table_container') return self.validate(expectedValues) except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False
def load(self): self.util = UtilityFunctions(self.driver) try: # Crap on left self.forgotPwForm = forgotPwForm.ForgotPwForm(self.driver) self.signIn_link = self.driver.find_elements_by_tag_name('a')[-1] self.validate() return True except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False
def __init__(self, driver): self.driver = driver self.util = UtilityFunctions(self.driver) self.months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] count = 0 loaded = False while not loaded and count < 5: loaded = self.load() count += 1 time.sleep(.2)
def load(self, expectedInfo=None, editMode=False): try: WDW(self.driver, 20).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.util = UtilityFunctions(self.driver) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) # print('0') # Verify consent form is in expected mode (normal or edit) if self.edit_mode() != editMode: print('ConsentForm: Incorrect mode. Expected editMode ' + str(editMode)) return False self.form = self.driver.find_elements_by_tag_name('form')[1] # print('1') try: self.facility_name = self.form.find_elements_by_class_name('font-weight-bold')[1].text except NoSuchElementException: # Facility name is not required field on previous page (for now) self.facility_name = None # print('2') self.load_preferences() # print('3') self.other_input = self.form.find_element_by_id('other_value') # print('4') # Patient Info self.first_name = self.form.find_element_by_id('patient_firstName') self.last_name = self.form.find_element_by_id('patient_lastName') self.rep_first_name = self.form.find_element_by_id('representative_firstName') self.rep_last_name = self.form.find_element_by_id('representative_lastName') self.date_input = self.form.find_element_by_id('dateField') # print('5') # Portal Info self.load_portal_login_info(editMode) # print('6') # Order is not same as displayed on page (float right) self.buttons = self.form.find_elements_by_class_name('green-hvr-bounce-to-top') self.agree_button = self.buttons[0] self.do_not_agree_button = self.buttons[1] self.print_button = self.buttons[2] self.back_button = self.buttons[3] # print('7') return self.validate(expectedInfo) except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False
def load(self, labInfo=None): try: WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.util = UtilityFunctions(self.driver) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) self.form = self.driver.find_element_by_id('page-content-wrapper') buttons = self.form.find_elements_by_tag_name('button') inputs = self.form.find_elements_by_tag_name('input') self.add_new_labs = buttons[0] self.get_my_labs = buttons[1] # Is this here all the time? # Lab Values Chart chart_cont = self.driver.find_element_by_class_name( 'myeloma-labs-custom') self.lab_values_dropdown = chart_cont.find_element_by_tag_name( 'button') # Date range options range_cont = self.driver.find_element_by_class_name('datenfilter') date_buttons = range_cont.find_elements_by_tag_name('button') self.three_month_button = date_buttons[0] self.six_month_button = date_buttons[1] self.year_to_date_button = date_buttons[2] self.one_year_button = date_buttons[3] self.two_year_button = date_buttons[4] self.five_year_button = date_buttons[5] self.ten_year_button = date_buttons[6] self.all_button = date_buttons[7] # Custom date range inputs = range_cont.find_elements_by_tag_name('input') self.from_date_input = inputs[0] self.to_date_input = inputs[1] # Lab Values Table self.load_table() self.continue_button = buttons[10] # self.validate(labInfo) return True except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False
def load(self, riskInfo=None): self.util = UtilityFunctions(self.driver) try: WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) self.load_test_table() # When user has already filled out info # addDiagnosisButtons = self.driver.find_elements_by_class_name('addDiagnoisisButton') # self.add_fish_button = addDiagnosisButtons[0] # self.add_gep_button = addDiagnosisButtons[1] # self.add_ngs_button = addDiagnosisButtons[2] # buttons = self.driver.find_elements_by_tag_name('button') # self.upload_file_button = buttons[2] # cont = self.driver.find_element_by_class_name('genetics-btn') # self.continue_button = cont.find_element_by_tag_name('button') # # self.load_fish_table() # # self.load_gep_table() # # self.load_ngs_table() # # self.load_highRisk_table() # self.container = self.driver.find_element_by_id('page-content-wrapper') # tooltips = self.container.find_elements_by_tag_name('img') # self.fish_tooltip = tooltips[0] # self.gep_tooltip = tooltips[1] # self.ngs_tooltip = tooltips[2] # self.high_risk_tooltip = tooltips[3] # When user hasn't filled anything out # todo return True except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False
class HealthLifestyleForm(): def __init__(self, driver): self.driver = driver self.util = UtilityFunctions(self.driver) self.load() def load(self): WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) time.sleep(1) self.form = self.driver.find_elements_by_tag_name('form')[-1] self.sectionConts = self.form.find_elements_by_class_name( 'after-head-row') self.load_sections() self.save_button = self.form.find_element_by_tag_name('button') # print('sections: ' + str(self.sections)) # self.validate() return True def load_sections(self): self.sections = [] for i, section in enumerate(self.sectionConts): # print('loading section: ' + str(i)) # Contains primary and any visible secondary questions self.questionContainers = section.find_elements_by_class_name( 'ques_group_cls') self.subQuestionIndices = [] questionList = [] for questionIndex, questionContainer in enumerate( self.questionContainers): # print('loading question: ' + str(questionIndex)) # Primary or secondary question? subquestions = questionContainer.find_elements_by_class_name( 'ques_group_cls') if len(subquestions) > 0: for subquestionIndex in xrange(len(subquestions)): subIndex = questionIndex + 1 + subquestionIndex print('subquestion: ' + str(subIndex)) self.subQuestionIndices.append(subIndex) if questionIndex not in self.subQuestionIndices: # Primary question questionList.append(self.load_questions(questionContainer)) self.sections.append(questionList) def load_questions(self, questionContainer, isSecondary=False): question = {} questionIndex = None # First is primary. Any additional ones are secondary questionConts = questionContainer.find_elements_by_class_name( 'cls_survey_question') if isSecondary: questionConts = [questionContainer] for i, questionCont in enumerate(questionConts): textInput = None radioOptions = None options = {} secondary_questions = [] if i == 0: # Primary try: # look for radio options radioContainers = questionCont.find_elements_by_class_name( 'dynamic-radio') dropdownContainers = questionCont.find_elements_by_class_name( 'is-clearable') for radioCont in radioContainers: inputs = radioCont.find_elements_by_tag_name('input') spans = radioCont.find_elements_by_tag_name('span') optionName = self.util.get_text(spans[0]).lower() options[optionName] = inputs[0] if dropdownContainers: question['dropdowns'] = dropdownContainers if len(radioContainers) == 0 and len( dropdownContainers) == 0: textInput = questionCont.find_element_by_tag_name( 'input') except NoSuchElementException: pass # Look for an input else: # secondary secondary_questions.append( self.load_questions(questionCont, True)) question['container'] = questionCont if options: question['options'] = options if textInput: question['textInput'] = textInput if secondary_questions: question['secondary_questions'] = secondary_questions return question def set_dropdown(self, container, value): # Figure out if you need to click 'Select-value-label' or 'Select-placeholder' element dropdown_preSet = False try: dropdown_value = container.find_element_by_class_name( 'Select-value-label') dropdown_placeholder = None dropdown_preSet = True except NoSuchElementException: dropdown_value = None dropdown_placeholder = container.find_element_by_class_name( 'Select-placeholder') # click it if dropdown_preSet: dropdown_value.click() else: dropdown_placeholder.click() # load options in dropdown options = {} try: menu = self.form.find_element_by_class_name('Select-menu-outer') divs = menu.find_elements_by_tag_name('div') for i, div in enumerate(divs): if i != 0: options[div.text.lower()] = divs[i] except NoSuchElementException: print('Unable to find dropdown items for first diagnosis') # click option try: option = options[value.lower()] option.click() except (IndexError, KeyError) as e: print('invalid index: ' + value) for option in options: print(option)
class SingleDatePicker(): def __init__(self, driver): self.driver = driver self.util = UtilityFunctions(self.driver) self.months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] count = 0 loaded = False while not loaded and count < 5: loaded = self.load() count += 1 time.sleep(.2) def load(self): try: self.container = self.load_container() if self.container: self.month = self.container.find_element_by_class_name( 'cur-month') self.year = self.container.find_element_by_class_name( 'cur-year') self.day_cont = self.container.find_element_by_class_name( 'dayContainer') self.today = self.try_load_today() self.selected_day = self.try_load_selected_day() return True else: print('singleDatePicker: Could not find an open container') except NoSuchElementException: print('failed to load datepicker') return False def load_container(self): # For some reason has multiple 'months' of dates loaded. Month actually displayed is in last container containers = self.driver.find_elements_by_class_name( 'flatpickr-calendar') container = None for i, cont in enumerate(containers): classes = cont.get_attribute('class') if 'open' in classes: container = cont return container def try_load_today(self): # Won't have 'today' if input already has today's date or current month is not selected today = None try: today = self.day_cont.find_element_by_class_name('today') except NoSuchElementException: pass return today def try_load_selected_day(self): # May not have a day selected on displayed month (or at all) selectedEl = None try: selectedEl = self.day_cont.find_element_by_class_name( 'selected').text except NoSuchElementException: pass return selectedEl ########################### General ############################## def set_date(self, date): # Expects 'MM/DD/YYYY' format if date == 'current': self.set_current_date() else: self.set_year(date[-4:]) # raw_input('set year?') self.set_month(date[:2]) # raw_input('set month?') self.set_day(date[3:5]) # raw_input('set day?') self.load() def set_current_date(self): now = datetime.datetime.now() self.set_date(now.strftime("%m/%d/%Y")) def get_date(self): # Return datepicker's value in MM/DD/YYYY format (current selection, not input value) # day will be '' if nothing is selected ('MM//YYYY') month = self.month_int(self.month.text) year = self.year.get_attribute('value') day = self.day_int(self.selected_day) date = month + '/' + day + '/' + year return {'month': month, 'year': year, 'day': day, 'date': date} def set_year(self, year): print('setting year: ' + str(year)) current_year = self.year.get_attribute('value') count = 0 while year != current_year and count < 50: if current_year > year: # 2018 > 2017 year_down = self.container.find_element_by_class_name( 'arrowDown') self.util.click_el(year_down) elif current_year < year: year_up = self.container.find_element_by_class_name('arrowUp') self.util.click_el(year_up) time.sleep(.4) self.load() current_year = self.year.get_attribute('value') count += 1 def set_month(self, month): print('setting month: ' + str(month)) current_month = self.month_int(self.month.text) count = 0 while current_month != month and count < 12: if current_month > month: print(str(current_month) + " > " + str(month)) month_back = self.container.find_element_by_class_name( 'flatpickr-prev-month') self.util.click_el(month_back) elif current_month < month: print(str(current_month) + " < " + str(month)) month_next = self.container.find_element_by_class_name( 'flatpickr-next-month') self.util.click_el(month_next) time.sleep(.4) self.load() current_month = self.month_int(self.month.text) count += 1 def set_day(self, day): print('setting day: ' + str(day)) errorFree = False count = 0 while not errorFree and count < 10: try: days = self.day_cont.find_elements_by_class_name( 'flatpickr-day') for i, dayEl in enumerate(days): classes = dayEl.get_attribute('class') if 'nextMonthDay' not in classes and 'prevMonthDay' not in classes: # print(dayEl.text) if int(dayEl.text) == int(day): # print('clicking ' + dayEl.text) self.util.click_el(dayEl) errorFree = True except StaleElementReferenceException: print('failed to set day: ' + str(count)) count += 1 def validate_month(self, month): # Compare 'month' to picker's current month (MM format) matches = True # print('picker month: ' + str(self.month.text)) # print('expected raw: ' + str(month)) # print('expected parsed: ' + self.months[self]) if self.months[month - 1] != self.month.text: matches = False return matches def validate_day(self, day): # Compare 'day' to picker's current day (DD format) # Pass in None if not expecting a day selected # if self.selected_day: # print('picker day: ' + str(self.selected_day.text)) # else: # print('picker day: None') # print('expected: ' + str(day)) matches = False if day == self.selected_day or day == self.selected_day.text: # No day selected or values match matches = True return matches def validate_year(self, year): # Compare 'year' to picker's current year (YYYY format) # print('picker year: ' + str(self.year.get_attribute('value'))) # print('expected year: ' + str(year)) matches = True if self.year.get_attribute('value') != str(year): matches = False return matches def has_current_date(self): # Return 'current' if picker has today's date now = datetime.datetime.now() currentDate = 'current' now.strftime("%m/%d/%Y") if int(now.strftime("%Y")) != int(self.year.get_attribute('value')): print('Not current year: ' + str( now.strftime("%Y") + ', ' + str(self.year.get_attribute('value')))) currentDate = False if self.months[now.month - 1] != self.month.text: print('Not current month: ' + self.months[now.month - 1] + ', ' + str(self.month.text)) currentDate = False if int(now.day) != int(self.selected_day): print('Not current day: ' + str(now.day) + ', ' + self.selected_day) currentDate = False return currentDate def month_int(self, value): # Given name of month, return string of name converted to integer (January = '01') return str(self.months.index(value) + 1).zfill(2) def day_int(self, value): if value: return value.zfill(2) else: return ''
class DatePicker(): """Date picker for MonthYear input""" def __init__(self, driver, container): self.driver = driver # Throw exception if container doesn't contain date stuff cont = container.find_element_by_class_name('Select--single') self.container = container self.util = UtilityFunctions(self.driver) def load(self, expectedState=None): try: # self.picker_state = self.get_picker_state() # if self.picker_state == 'wrong container': # print('wrong datepicker container') # return False # else: dropdownConts = self.container.find_elements_by_class_name( 'Select--single') if len(dropdownConts) < 2: print('not enough dropdown containers') return False self.month_cont = dropdownConts[0] self.year_cont = dropdownConts[1] return True except (NoSuchElementException, StaleElementReferenceException) as e: print('failed to load datePicker') return False def get_picker_state(self): state = 'normal' # Make sure container has datePicker in it try: cont = self.container.find_element_by_class_name('Select--single') except NoSuchElementException: state = 'wrong container' return state ########################### General ############################## def set_date(self, date): month = self.parse_date(date, 'month') year = self.parse_date(date, 'year') self.load() print('setting date') print(month) print(year) WDW(self.driver, 10).until(lambda x: self.set_dropdown(self.month_cont, month)) WDW(self.driver, 10).until(lambda x: self.set_dropdown(self.year_cont, year)) # Wait for datepicker to disappear time.sleep(.4) def set_dropdown(self, container, value): # Figure out if you need to click 'Select-value-label' or 'Select-placeholder' element dropdown_preSet = False try: dropdown_value = container.find_element_by_class_name( 'Select-value-label') dropdown_placeholder = None dropdown_preSet = True except NoSuchElementException: dropdown_value = None dropdown_placeholder = container.find_element_by_class_name( 'Select-placeholder') # Only continue if value isn't already set if dropdown_value and self.util.get_text(dropdown_value) == value: return True # click it if dropdown_preSet: dropdown_value.click() else: dropdown_placeholder.click() # load options in dropdown options = {} count = 0 loaded = False while not loaded and count < 5: try: menu = container.find_element_by_class_name( 'Select-menu-outer') divs = menu.find_elements_by_tag_name('div') for i, div in enumerate(divs): if i != 0: options[self.util.get_text(div).lower()] = divs[i] loaded = True except NoSuchElementException: print('Unable to find dropdown items for datepicker') count += 1 if count == 5 or not options: print('Failed to load date dropdown options') return False # click option try: option = options[value.lower()] option.click() return True except (IndexError, KeyError) as e: print('invalid date option: ' + value) for option in options: print(option) def parse_date(self, dateStr, dateType): # Given dateStr "mm/yyyy", parse and return month or year divider = dateStr.index('/') # divider should always be 2 if divider != 2: print('Trying to set invalid date: ' + str(dateStr)) if dateType == 'month': months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] return months[int(dateStr[:divider]) - 1] else: year = dateStr[divider + 1:] return year
class TreatmentsOutcomesView(view.View): post_url = 'about-me' def load(self, expectedValues=None, expectedState=None): try: WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.util = UtilityFunctions(self.driver) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) self.state = self.load_state() if expectedState and expectedState != self.state: print('Wrong state! Expected ' + str(expectedState) + ', got ' + str(self.state)) return False if self.state == 'fresh': self.newAccountPopUpForm = newAccountPopUpForm.NewAccountPopUpForm( self.driver) # load new popup # todo: need new account to get this state pass else: try: # Only shows up when certain diagnoses are selected on 'Myeloma Diagnosis' self.view_options_button = self.driver.find_element_by_class_name( 'treatment_op_btn') except NoSuchElementException: self.view_options_button = None self.load_add_treatment_button() self.saved_tests = self.driver.find_elements_by_class_name( 'table_container') return self.validate(expectedValues) except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False def load_state(self): # New user gets popup asking whether they have received treatments before (yes/no) # Todo: figure out how to load popup # Saved treatment? try: savedTable = self.driver.find_element_by_class_name( 'outer-mypataient-table') return 'saved' except NoSuchElementException: # normal? try: buttonCont = self.driver.find_element_by_class_name( 'custom1-add-treatment-btn') return 'normal' except NoSuchElementException: return 'fresh' def load_add_treatment_button(self): buttonCont = self.driver.find_element_by_class_name( 'custom1-add-treatment-btn') self.add_treatments_button = buttonCont.find_elements_by_tag_name( 'button')[0] def validate(self, expectedValues): self.failures = [] if expectedValues: print('validating expectedValues') meta = expectedValues.get('meta', None) if meta: for key, value in meta.iteritems(): if key == 'num_treatments': if value != len(self.saved_tests): self.failures.append( 'Treatments&Outcomes Meta: Expected ' + str(value) + ' treatments. Form has ' + str(len(self.saved_tests))) else: print('correct number of treatents: ' + str(value)) elif self.state == 'fresh': # todo: Validate text on 'fresh' popup print('validating fresh') pass else: if self.add_treatments_button and self.util.get_text( self.add_treatments_button) != 'Add Treatments': self.failures.append( 'treatmentsOutcomesView: Unexpected text on add treatment button' ) if self.state == 'saved': print('validating saved') # Verify tests have expected data extraTypes = [ 'bone strengtheners', 'antibiotics', 'antifungal' ] expectedTests = expectedValues.get('tests', {}) for testIndex, test in enumerate(expectedTests): print('T&O: Validating test: ' + str(testIndex)) # Test meta data testType = test['testMeta']['type'] numQuestions = len(test['questions']) # read data out of test's table # if only validating 1 test, make sure grabbing last loadedTest if len(expectedTests) == 1: testIndex = -1 savedTest = self.read_test(testIndex) # raw_input('savedTest: ' + str(savedTest)) savedData = savedTest['testData'] try: if testType == 'clinical': self.compare_nct(savedData['nct #'], test, testType) self.compare_treatments( savedData['treatment type'], test, testType) else: # All other treatment types have treatments and therapy type self.compare_therapy_type( savedData['therapy type'], test, testType) self.compare_treatments( savedData['treatments'], test, testType) if testType == 'stem cell': self.compare_start_date( self.convert_date( savedData['transplant date']), test, testType) else: self.compare_start_date( self.convert_date(savedData['start date']), test, testType) self.compare_end_date( self.convert_date(savedData['end date']), test, testType) if testType in extraTypes: # Bone Strengtheners, Antibiotics, Antifungal self.compare_frequency(savedData['frequency'], test, testType) else: # Chemo, Radiation, Stem Cell self.compare_side_effects( savedData['side effects'], test, testType) self.compare_outcome(savedData['outcome'], test, testType) except KeyError: print(savedData) raw_input('keyerror: ?') elif self.state == 'normal': print('validating normal') pass if len(self.failures) > 0: print('Failures!') for failure in self.failures: print(failure) raise NoSuchElementException( "Failed to load treatmentsOutcomesView") else: return True def read_test(self, testIndex): # 'actions': {'treatments': webEl, 'outcomes': webEl, 'sideEffects': webEl, 'delete': webEl} # 'testData': { # 'start date': 'Jan 2018', # 'end date': 'Current Treatment', # 'therapy type': 'Maintenance Therapy', # 'treatments': ['melphalan', 'Adriamycin (Removed On: Mar 2018) (Reason: Drug cost)'], # 'side effects': {'blood clots': {'intensity': 9}, 'irregular/rapid heartbeat': {'intensity': 2}} # } testData = {} treatments = [] sideEffects = {} actions = {} cont = self.saved_tests[testIndex] rows = cont.find_elements_by_tag_name('tr') testKeys = [ ] # ['start date', 'end date', 'therapy type', 'treatments', 'side effects'] for rowIndex, row in enumerate(rows): # Header values if rowIndex == 0: tds = row.find_elements_by_tag_name('td') for td in tds: testKeys.append(self.util.get_text(td).lower()) # Test values elif rowIndex == 1: tds = row.find_elements_by_tag_name('td') for tdIndex, td in enumerate(tds): key = testKeys[tdIndex] if tdIndex == len( tds) - 2: # Treatments List (2nd to last td) items = td.find_elements_by_class_name( 'treatments-lbl-span') for treatment in items: treatmentText = self.util.get_text( treatment).lower() treatments.append(treatmentText) # Clinical doesn't have items (just text) if not items: text = self.util.get_text(td) if text: treatments.append(text.lower()) else: raw_input('wtf?') # try: # treatments.append(self.util.get_text(td)).lower() # except AttributeError: # raw_input(str(key) + '?') testData[key] = treatments elif tdIndex == len( tds) - 1: # Last row: index=4 (3 for stem cell) # Side Effects (chemo, radiation, stem cell) items = td.find_elements_by_class_name( 'treatments-lbl-span') if len(items) > 0: for effect in items: # Leave in upper case. Data passed in is in upper case name = self.util.get_text( effect.find_element_by_tag_name('span')) intensity = int( self.util.get_text( effect.find_element_by_tag_name( 'div'))) sideEffects[name] = {'intensity': intensity} testData[key] = sideEffects else: # Frequency (Bone strengtheners, antibiotics, antifungal) # Only bone strengtheners have frequency (otherwise 'N/A') text = self.util.get_text(td).lower() print('text: ' + str(text)) if text: testData[key] = text else: # Might have no side effects (any type of treatment) testData[key] = sideEffects else: # Start date, end date, therapy type testData[key] = self.util.get_text(td).lower() # Outcome (no outcome for bone strengtheners, antibiotics, antifungal. Table only has 3 rows) elif rowIndex == 2 and len(rows) == 4: td = row.find_elements_by_tag_name('td')[ 1] # text is in 2nd td testData['outcome'] = self.util.get_text(td).lower() # Actions (last row) elif (rowIndex + 1) == len(rows): anchors = row.find_elements_by_tag_name('a') if len(anchors) == 4: actions['treatments'] = anchors[0] actions['outcomes'] = anchors[1] actions['sideEffects'] = anchors[2] actions['delete'] = anchors[3] elif len(anchors ) == 2: # bone strengtheners, antibiotics, antifungal actions['treatments'] = anchors[0] actions['delete'] = anchors[1] # print('done loading test: ' + str(testIndex)) return { 'actions': actions, 'testData': testData, } def convert_date(self, dateStr): # Input: 'mmm yyyy', Output; 'mm/yyyy' spaceIndex = dateStr.find(' ') # Should always be 3 if spaceIndex == 3: months = [ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ] monthName = dateStr[:3] year = dateStr[4:] month = str(months.index(monthName) + 1).zfill(2) return month + '/' + str(year) else: if dateStr != 'current treatment': print('Unexpected date format: ' + str(dateStr)) return dateStr def parse_sideEffects(self, info): # {'cardiovascular/circulatory system': { # 'irregular/rapid heartbeat': {'intensity': 2}, # 'blood clots': {'intensity': 9}} # } # converted to... # {u'irregular/rapid heartbeat': {'intensity': u'2'}, # u'blood clots': {'intensity': u'9'} # } sideEffects = {} if info: for category in info: for effect, value in info[category].iteritems(): sideEffects[effect] = value return sideEffects def calc_start_date(self, testType, test): # Stem Cell: question[3] unless it's induction therapy (question[2]=yes), then it's 8 if testType == 'stem cell': index = 3 for key in test['questions'][2]['options']: if key.lower() == 'yes': index = 8 return index def compare_start_date(self, savedVal, test, testType): questionIndicies = { 'stem cell': self.calc_start_date(testType, test), 'radiation': 2, 'chemo': 1, 'bone strengtheners': 3, 'antibiotics': 3, 'antifungal': 3, 'clinical': 2, } # Start Date (universal treatment option) questionIndex = questionIndicies[testType] expectedVal = test['questions'][questionIndex]['text'] if savedVal != expectedVal: self.failures.append('T&Outcomes: Expected start date ' + str(expectedVal) + ', loaded ' + str(savedVal)) else: print('correct start date') def compare_end_date(self, savedVal, test, testType): if testType == 'radiation': expectedVal = test['questions'][3]['text'] elif testType == 'chemo': expectedVal = 'current treatment' if test['questions'][3]['type'] == 'date': expectedVal = test['questions'][3]['text'] elif testType == 'clinical': expectedVal = 'current treatment' if test['questions'][4]['type'] == 'date': expectedVal = test['questions'][4]['text'] else: try: expectedVal = test['questions'][5][ 'text'] # If no question[5] it's 'current treatment' except (IndexError, KeyError) as e: # No end date expectedVal = 'current treatment' if savedVal != expectedVal: self.failures.append('T&Outcomes: Expected end date ' + str(expectedVal) + ', loaded ' + str(savedVal)) else: print('correct end date') def compare_therapy_type(self, savedVal, test, testType): if testType == 'radiation': expectedVal = 'radiation' elif testType == 'stem cell': expectedVal = 'stem cell transplant' elif testType == 'chemo': # If it's not maintenance therapy, ExpectedVal is option from 1st question # Index of maintenance therapy question depends on if treatment is 'current' or not expectedVal = 'current treatment' maintenanceIndex = 3 if test['questions'][3]['type'] == 'date': # Is a current treatment. Maintenance is index 4 maintenanceIndex = 4 isMaintenance = False for key in test['questions'][maintenanceIndex]['options']: if key.lower() == 'yes': expectedVal = 'maintenance therapy' else: # Don't pull from question options. Exact text does not match expectedVal = 'Chemotherapy / Myeloma Therapy'.lower() else: for key in test['questions'][1]['options']: expectedVal = key.lower() if savedVal != expectedVal: self.failures.append('T&Outcomes: Expected therapyType ' + str(expectedVal) + ', loaded ' + str(savedVal)) else: print('correct therapy type') def compare_side_effects(self, savedVal, test, testType): # Everything has sideEffects except for 'extra' treatments index = -1 if testType == 'stem cell': index = -2 expectedVal = self.parse_sideEffects( test['questions'][index]['options']) # print('expectedVal: ' + str(expectedVal)) if savedVal != expectedVal: self.failures.append('T&Outcomes: Expected sideEffects ' + str(expectedVal) + ', loaded ' + str(savedVal)) else: print('correct side effects') def compare_treatments(self, savedVal, test, testType): # SavedVal should be a list with all the treatment options expectedVal = None if testType == 'clinical': # Clinical shouldn't have multiple 'options', just text from question 4/5 # question[4] might be stop date if test['questions'][4].get('type', None) == 'input': expectedVal = test['questions'][4].get('text', None) else: expectedVal = test['questions'][5].get('text', None) if expectedVal: expectedVal = ['clinical trial: ' + expectedVal.lower()] else: print('Not evaluating treatments for testType: ' + str(testType)) if expectedVal: if savedVal != expectedVal: self.failures.append('T&Outcomes: Expected treatment ' + str(expectedVal) + ', loaded ' + str(savedVal)) else: print('correct treatment') def compare_frequency(self, savedVal, test, testType): # Only for Bone strengthener, antibiotics, antifungal if testType == 'bone strengtheners': for key in test['questions'][-1]['options']: expectedVal = key.lower() else: expectedVal = 'na' if savedVal != expectedVal: self.failures.append('T&Outcomes: Expected frequency ' + str(expectedVal) + ', loaded ' + str(savedVal)) else: print('correct frequency') def compare_nct(self, savedVal, test, testType): expectedVal = None if testType == 'clinical': expectedVal = test['questions'][1]['text'].lower() if expectedVal and savedVal != expectedVal: self.failures.append('T&Outcomes: Expected NCT# ' + str(expectedVal) + ', loaded ' + str(savedVal)) else: print('correct nct') def compare_outcome(self, savedVal, test, testType): # Only for chemo, radiation, stem cell expectedOutcomes = [] index = -2 if testType == 'stem cell': index = -3 options = test['questions'][index]['options'] for optionName, value in options.iteritems(): expectedOutcomes.append(optionName.lower()) # 'options': { # 'I discontinued this treatment': { # 'type': 'select-all', # 'options': { # 'Too much travel': {}, # 'Other': {'comment': 'Discontinued comment: Treatment2'}, # }, # } if expectedOutcomes[0] == 'i discontinued this treatment': # There's subquestions. Get expected options for subquestion suboptions = options['I discontinued this treatment']['options'] for suboption, value in suboptions.iteritems(): expectedOutcomes.append(suboption.lower()) # Get comment if 'other' is selected if suboption.lower() == 'other': try: comment = value['comment'] expectedOutcomes.append(comment.lower()) except AttributeError: print('No comment') hasError = False for expectedOutcome in expectedOutcomes: if not expectedOutcome in savedVal: self.failures.append('T&Outcomes: Expected outcome ' + str(expectedOutcome) + ', loaded ' + str(savedVal)) hasError = True if not hasError: print('correct outcome') ############################ Utility Functions ############################### def delete_treatment(self): self.popUpForm = popUpForm.PopUpForm(self.driver) WDW(self.driver, 20).until(lambda x: self.popUpForm.load()) self.popUpForm.confirm('confirm') WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) def edit_treatments(self, editInfo, expectedInfo): self.editTreatmentForm = editTreatmentForm.EditTreatmentForm( self.driver) WDW(self.driver, 20).until(lambda x: self.editTreatmentForm.load()) if self.editTreatmentForm.edit_treatment(editInfo): WDW(self.driver, 20).until( lambda x: self.load({'tests': [expectedInfo]}, 'saved')) def edit_outcomes(self, editInfo, expectedInfo): self.popUpEditor = editTreatmentPopup.EditTreatmentPopup(self.driver) WDW(self.driver, 20).until(lambda x: self.popUpEditor.load()) if self.popUpEditor.edit_treatment(editInfo, 'outcomes'): WDW(self.driver, 20).until( lambda x: self.load({'tests': [expectedInfo]}, 'saved')) def edit_side_effects(self, editInfo, expectedInfo): self.popUpEditor = editTreatmentPopup.EditTreatmentPopup(self.driver) WDW(self.driver, 20).until(lambda x: self.popUpEditor.load()) if self.popUpEditor.edit_treatment(editInfo, 'side effects'): WDW(self.driver, 20).until( lambda x: self.load({'tests': [expectedInfo]}, 'saved')) def load_actions(self, tableContainer): lastRow = tableContainer.find_elements_by_tag_name('tr')[-1] links = lastRow.find_elements_by_tag_name('a') if len(links) == 4: return { 'treatments': links[0], 'outcomes': links[1], 'side effects': links[2], 'delete': links[3], } elif len(links) == 2: # Bone Strengtheners, Antibiotics, Anti Fungals return { 'treatments': links[0], 'delete': links[1], } def click_add_treatment(self): # Sometimes thinks there's an element in the way of button clicked = False count = 0 while not clicked and count < 5: # Has issues clicking for some reason. try: buttonCont = self.driver.find_element_by_class_name( 'custom1-add-treatment-btn') button = buttonCont.find_elements_by_tag_name('button')[0] self.util.click_el(button) clicked = True except WebDriverException: print('could not click add treatment button: ' + str(count)) time.sleep(.4) pass count += 1 if count == 5: print('failed to click add treatment button') def get_treatment_type(self, treatmentIndex): # Normal: Chemo, Radiation, Stem Cell, Clinical. # Extra: Bone strengtheners, antibiotics antifungal test = self.read_test(treatmentIndex) num_actions = len(test['actions']) if num_actions == 2: return 'extra' elif num_actions == 4: return 'normal' else: print('unexpected number of treatment actions: ' + str(num_actions)) return False ############################### Test Functions. #################################### def add_treatment(self, treatmentInfo, expectedInfo=None, expectedError=None, expectedWarnings=None): # ExpectedInfo should be list of expected tests if expectedInfo is None: expectedInfo = [treatmentInfo] try: # print(self.state) if self.state == 'normal' or self.state == 'saved': self.click_add_treatment() self.addTreatmentForm = addTreatmentForm.AddTreatmentForm( self.driver) WDW(self.driver, 10).until(lambda x: self.addTreatmentForm.load()) if self.addTreatmentForm.add_treatment(treatmentInfo): WDW(self.driver, 10).until( lambda x: self.load({'tests': expectedInfo}, 'saved')) else: print('Failed to add treatment') else: # todo: handle fresh popup pass return True except MsgError: # Is add treatment expected to fail? errorType = self.error['errorType'] if expectedError and errorType.lower() == expectedError.lower(): return True print(self.error['errorMsg']) if errorType == 'undefined': print('Undefined error: ' + self.error['errorText']) except WarningError: # Is form submission expected to have warning? unexpectedWarnings = [] if expectedWarnings: # Go through self.warnings and check each warningType matches an expectedWarning # Append warnings that aren't expected to unexpectedWarnings for i, warning in enumerate(self.warnings): expected = False warningType = warning['type'] for expectedWarning in expectedWarnings: if expectedWarning == warningType: expected = True if not expected: unexpectedWarnings.append(self.warnings[i]) if unexpectedWarnings: for unexpected in unexpectedWarnings: print(unexpected['msg']) if warningType == 'undefined': print('Undefined warning: ' + unexpected['text']) else: return True return True def edit_treatment(self, treatmentIndex, editType, expectedInfo=None, editInfo=None, popupAction='confirm'): if self.state == 'saved': actions = self.load_actions(self.saved_tests[treatmentIndex]) try: action = actions[editType] self.util.click_el(action) except KeyError: print(str(editType) + ' Is not a valid treatment option') raise KeyError('Not a valid treatment option') if editType == 'delete': self.delete_treatment() else: if editType == 'treatments': self.edit_treatments(editInfo, expectedInfo) elif editType == 'outcomes': self.edit_outcomes(editInfo, expectedInfo) elif editType == 'side effects': self.edit_side_effects(editInfo, expectedInfo) # self.clear_alert() print('Done editing: ' + str(editType)) def delete_all_treatments(self): if self.state == 'saved': num_treatments = len(self.saved_tests) for i, saved_test in enumerate(self.saved_tests): print('deleting treatment #' + str(i)) actions = self.load_actions(self.saved_tests[0]) try: self.util.click_el(actions['delete']) except KeyError: print('"delete" Is not a valid treatment option') raise KeyError('Not a valid treatment option') self.delete_treatment() # Should be 1 less treatment WDW(self.driver, 10).until(lambda x: self.load( {'meta': { 'num_treatments': num_treatments - (i + 1) }})) def view_options(self): if self.view_options_button: self.util.click_el(self.view_options_button) url = self.driver.current_url if '/treatment-options' not in url: return False else: print( 'Treatment & Outcomes view does not have "View Options" button' ) return False
class FullHealthMyelomaForm(): def __init__(self, driver): self.driver = driver self.util = UtilityFunctions(self.driver) self.load() def load(self): WDW(self.driver, 20).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) time.sleep(1) self.form = self.driver.find_elements_by_tag_name('form')[-1] self.sectionConts = self.form.find_elements_by_class_name('after-head-row') self.load_sections() self.save_button = self.form.find_element_by_tag_name('button') # self.sections = [ # {'1': [ # {'options': { # 'yes': inputEl, # 'no': inputEl, # }}, # {'date': inputEl}, # ]}, # ] # Get input for 1st section, 2st row, second question 'yes' # self.sections[0][1]['2']['options']['yes'] def load_sections(self): self.sections = [] for i, section in enumerate(self.sectionConts): # print('loading section: ' + str(i)) # Contains primary and any visible secondary questions self.questionContainers = section.find_elements_by_class_name('ques_group_cls') self.subQuestionIndices = [] questionList = [] for questionIndex, questionContainer in enumerate(self.questionContainers): # print('loading question: ' + str(questionIndex)) # Primary or secondary question? subquestions = questionContainer.find_elements_by_class_name('ques_group_cls') if len(subquestions) > 0: for subquestionIndex in xrange(len(subquestions)): subIndex = questionIndex+1 + subquestionIndex print('subquestion: ' + str(subIndex)) self.subQuestionIndices.append(subIndex) if questionIndex not in self.subQuestionIndices: # Primary question questionList.append(self.load_questions(questionContainer)) self.sections.append(questionList) def load_questions(self, questionContainer, isSecondary=False): question = {} questionIndex = None # First is primary. Any additional ones are secondary questionConts = questionContainer.find_elements_by_class_name('cls_survey_question') if isSecondary: questionConts = [questionContainer] for i, questionCont in enumerate(questionConts): textInput = None radioOptions = None options = {} secondary_questions = [] if i == 0: # Primary try: # look for radio options radioContainers = questionCont.find_elements_by_class_name('dynamic-radio') for radioCont in radioContainers: inputs = radioCont.find_elements_by_tag_name('input') spans = radioCont.find_elements_by_tag_name('span') optionName = self.util.get_text(spans[0]).lower() options[optionName] = inputs[0] if len(radioContainers) == 0: textInput = questionCont.find_element_by_tag_name('input') except NoSuchElementException: pass # Look for an input else: # secondary secondary_questions.append(self.load_questions(questionCont, True)) question['container'] = questionCont if options: question['options'] = options if textInput: question['textInput'] = textInput if secondary_questions: question['secondary_questions'] = secondary_questions return question
def __init__(self, driver): self.driver = driver self.util = UtilityFunctions(self.driver) self.load()
def __init__(self, driver, container): self.driver = driver # Throw exception if container doesn't contain date stuff cont = container.find_element_by_class_name('Select--single') self.container = container self.util = UtilityFunctions(self.driver)
class ConsentFormView(view.View): post_url = 'consent-form' def load(self, expectedInfo=None, editMode=False): try: WDW(self.driver, 20).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.util = UtilityFunctions(self.driver) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) # print('0') # Verify consent form is in expected mode (normal or edit) if self.edit_mode() != editMode: print('ConsentForm: Incorrect mode. Expected editMode ' + str(editMode)) return False self.form = self.driver.find_elements_by_tag_name('form')[1] # print('1') try: self.facility_name = self.form.find_elements_by_class_name('font-weight-bold')[1].text except NoSuchElementException: # Facility name is not required field on previous page (for now) self.facility_name = None # print('2') self.load_preferences() # print('3') self.other_input = self.form.find_element_by_id('other_value') # print('4') # Patient Info self.first_name = self.form.find_element_by_id('patient_firstName') self.last_name = self.form.find_element_by_id('patient_lastName') self.rep_first_name = self.form.find_element_by_id('representative_firstName') self.rep_last_name = self.form.find_element_by_id('representative_lastName') self.date_input = self.form.find_element_by_id('dateField') # print('5') # Portal Info self.load_portal_login_info(editMode) # print('6') # Order is not same as displayed on page (float right) self.buttons = self.form.find_elements_by_class_name('green-hvr-bounce-to-top') self.agree_button = self.buttons[0] self.do_not_agree_button = self.buttons[1] self.print_button = self.buttons[2] self.back_button = self.buttons[3] # print('7') return self.validate(expectedInfo) except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False def edit_mode(self): # Is consent form in edit mode? try: # Look for edit button for Portal Login Information el = self.driver.find_element_by_class_name('info-edit') return True except NoSuchElementException: return False def load_portal_login_info(self, editMode): self.edit_login_info_button = self.try_load_edit_login_info_button() if editMode and self.login_info_mode() == 'noneditable': # No inputs. Load text as values vals = self.driver.find_elements_by_class_name('account-val') self.username = self.util.get_text(vals[0]) self.password = self.util.get_text(vals[1]) self.url = self.util.get_text(vals[2]) else: # Editable. Load input elements self.username = self.form.find_element_by_id('portal_username') self.password = self.form.find_element_by_id('portal_password') self.url = self.form.find_element_by_id('portal_url') def try_load_edit_login_info_button(self): # Button for entering edit mode for 'Patient Portal Login Information' # Only exists when editing consent form try: return self.driver.find_element_by_class_name('info-edit') except NoSuchElementException: return None def login_info_mode(self): # Is login information editable? try: # Look for non-editable fields els = self.driver.find_elements_by_class_name('account-val') if len(els) == 3: return 'noneditable' except NoSuchElementException: return 'editable' def validate(self, expectedInfo): failures = [] if len(self.buttons) != 4: failure.append('ConsentForm: Unexpected number of form buttons. Loaded ' + str(len(self.buttons))) if len(self.preference_inputs) != 12: failure.append('ConsentForm: Unexpected number of preference inputs. Loaded ' + str(len(self.preference_inputs))) if expectedInfo: # Validate facilities pass if len(failures) > 0: for failure in failures: print(failure) return False return True def load_preferences(self): self.preference_inputs = self.form.find_elements_by_class_name('checkbox-custom') self.preferences = {} for inputEl in self.preference_inputs: inputId = inputEl.get_attribute('id') self.preferences[inputId] = inputEl # 'access_all_records' # 'lab_reports' # 'history' # 'admission' # 'medication' # 'xray' # 'paperwork' # 'consult' # 'mental' # 'alcohol' # 'hiv' # 'other' def set_preferences(self, info, other_comment=None): for key in self.preferences: if key in info: # Make sure it's selected if not self.preferences[key].is_selected(): self.util.click_el(self.preferences[key]) else: # Make sure it's de-selected if self.preferences[key].is_selected(): self.util.click_el(self.preferences[key]) if other_comment: self.util.set_input(self.other_input, other_comment) def get_preferences(self): selected_preferences = [] for inputEl in self.preference_inputs: if inputEl.is_selected(): selected_preferences.append(inputEl.get_attribute('id')) return selected_preferences def set_patient_info(self, info, inputMethod='typed'): # Patient if 'first name' in info: self.util.set_input(self.first_name, info['first name']) if 'last name' in info: self.util.set_input(self.last_name, info['last name']) # Representative (optional) if 'rep first name' in info: self.util.set_input(self.rep_first_name, info['rep first name']) if 'rep last name' in info: self.util.set_input(self.rep_last_name, info['rep last name']) # Date if 'date' in info: self.set_date(info['date'], inputMethod) def get_patient_info(self, current_date=True): patient_info = {} patient_info['first name'] = self.first_name.get_attribute('value') patient_info['last name'] = self.last_name.get_attribute('value') patient_info['rep first name'] = self.rep_first_name.get_attribute('value') patient_info['rep last name'] = self.rep_last_name.get_attribute('value') if current_date: # Return 'current' if date is today's date self.util.click_el(self.date_input) self.picker = singleDatePicker.SingleDatePicker(self.driver) patient_info['date'] = self.picker.has_current_date() else: patient_info['date'] = self.date_input.get_attribute('value') return patient_info def set_date(self, date, inputMethod='typed'): if inputMethod == 'typed': self.util.set_input(self.date_input, date) # Typing value via selenium won't update date displayed on picker. Need to press enter self.date_input.send_keys(Keys.RETURN) elif inputMethod == 'picker': self.util.click_el(self.date_input) self.picker = singleDatePicker.SingleDatePicker(self.driver) self.picker.set_date(date) def compare_date(self, date, date_source='input'): # Compare given date w/ value of (input) or (picker) if date_source == 'input': now = datetime.datetime.now() curDate = now.strftime("%m/%d/%Y") return curDate == self.date_input.get_attribute('value') elif date_source == 'picker': self.util.click_el(self.date_input) self.picker = singleDatePicker.SingleDatePicker(self.driver) picker_date = self.picker.get_date() print(str(picker_date['date']) + ' == ' + str(date)) return date == picker_date['date'] def set_portal_info(self, info): if self.edit_mode() and self.login_info_mode() == 'uneditable': self.util.click_el(self.edit_login_info_button) time.sleep(.4) self.load() if info.get('username', None): self.util.set_input(self.username, info['username']) if info.get('password', None): self.util.set_input(self.password, info['password']) if info.get('url', None): self.util.set_input(self.url, info['url']) def get_portal_info(self): portal_info = {} editMode = self.edit_mode() portalInfoMode = self.login_info_mode() if editMode and portalInfoMode == 'noneditable': # Info is not editable. Password will be replaced w/ * characters portal_info['username'] = self.username portal_info['password'] = self.password portal_info['url'] = self.url else: portal_info['username'] = self.username.get_attribute('value') portal_info['password'] = self.password.get_attribute('value') portal_info['url'] = self.url.get_attribute('value') return portal_info def action(self, action='submit'): if action == 'submit': self.util.click_el(self.agree_button) elif action == 'back': self.util.click_el(self.back_button) elif action == 'do not agree': self.util.click_el(self.do_not_agree_button)
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 MyelomaLabsView(view.View): post_url = 'myeloma-labs' def load(self, labInfo=None): try: WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.util = UtilityFunctions(self.driver) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) self.form = self.driver.find_element_by_id('page-content-wrapper') buttons = self.form.find_elements_by_tag_name('button') inputs = self.form.find_elements_by_tag_name('input') self.add_new_labs = buttons[0] self.get_my_labs = buttons[1] # Is this here all the time? # Lab Values Chart chart_cont = self.driver.find_element_by_class_name( 'myeloma-labs-custom') self.lab_values_dropdown = chart_cont.find_element_by_tag_name( 'button') # Date range options range_cont = self.driver.find_element_by_class_name('datenfilter') date_buttons = range_cont.find_elements_by_tag_name('button') self.three_month_button = date_buttons[0] self.six_month_button = date_buttons[1] self.year_to_date_button = date_buttons[2] self.one_year_button = date_buttons[3] self.two_year_button = date_buttons[4] self.five_year_button = date_buttons[5] self.ten_year_button = date_buttons[6] self.all_button = date_buttons[7] # Custom date range inputs = range_cont.find_elements_by_tag_name('input') self.from_date_input = inputs[0] self.to_date_input = inputs[1] # Lab Values Table self.load_table() self.continue_button = buttons[10] # self.validate(labInfo) return True except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False def validate(self, labInfo): failures = [] lInfo = self.clinical_tables[-1] if lInfo: if labInfo: if lInfo['dobd'] != labInfo['dobd']: failures.append('Table value: ' + '"' + str(lInfo['dobd']) + '"' + ' expected ' + '"' + str(labInfo['dobd']) + '"') # 1: Clinical Trials if lInfo['monoclonal'] != labInfo['monoclonal']: failures.append('Table value: ' + '"' + str(lInfo['monoclonal']) + '"' + ' expected ' + '"' + str(labInfo['monoclonal']) + '"') if lInfo['kappa'] != labInfo['kappa']: failures.append('Table value: ' + '"' + str(lInfo['kappa']) + '"' + ' expected ' + '"' + str(labInfo['kappa']) + '"') if lInfo['lambda'] != labInfo['lambda']: failures.append('Table value: ' + '"' + str(lInfo['lambda']) + '"' + ' expected ' + '"' + str(labInfo['lambda']) + '"') if lInfo['ratio'] != labInfo['ratio']: failures.append('Table value: ' + '"' + str(lInfo['ratio']) + '"' + ' expected ' + '"' + str(labInfo['ratio']) + '"') if lInfo['bone_marrow'] != labInfo['bone_marrow']: failures.append('Table value: ' + '"' + str(lInfo['bone_marrow']) + '"' + ' expected ' + '"' + str(labInfo['bone_marrow']) + '"') if lInfo['creatinine'] != labInfo['creatinine']: failures.append('Table value: ' + '"' + str(lInfo['creatinine']) + '"' + ' expected ' + '"' + str(labInfo['creatinine']) + '"') if lInfo['platelets'] != labInfo['platelets']: failures.append('Table value: ' + '"' + str(lInfo['platelets']) + '"' + ' expected ' + '"' + str(labInfo['platelets']) + '"') if lInfo['neutrophils'] != labInfo['neutrophils']: failures.append('Table value: ' + '"' + str(lInfo['neutrophils']) + '"' + ' expected ' + '"' + str(labInfo['neutrophili']) + '"') # if lInfo['blood'] != labInfo['blood']: # failures.append('Table value: ' + '"' + str(lInfo['blood']) + '"' + ' expected ' + '"' + str(labInfo['blood']) + '"') # 2: Current state if lInfo['calcium'] != labInfo['calcium']: failures.append('Table value: ' + '"' + str(lInfo['calcium']) + '"' + ' expected ' + '"' + str(labInfo['calcium']) + '"') if lInfo['blood_cell'] != labInfo['blood_cell']: failures.append('Table value: ' + '"' + str(lInfo['blood_cell']) + '"' + ' expected ' + '"' + str(labInfo['blood_cell']) + '"') if lInfo['hemoglobin'] != labInfo['hemoglobin']: failures.append('Table value: ' + '"' + str(lInfo['hemoglobin']) + '"' + ' expected ' + '"' + str(labInfo['hemoglobin']) + '"') if lInfo['lactate'] != labInfo['lactate']: failures.append('Table value: ' + '"' + str(lInfo['lactate']) + '"' + ' expected ' + '"' + str(labInfo['lactate']) + '"') if lInfo['albumin'] != labInfo['albumin']: failures.append('Table value: ' + '"' + str(lInfo['albumin']) + '"' + ' expected ' + '"' + str(labInfo['albumin']) + '"') if lInfo['immuno_g'] != labInfo['immuno_g']: failures.append('Table value: ' + '"' + str(lInfo['immuno_g']) + '"' + ' expected ' + '"' + str(labInfo['immuno_g']) + '"') if lInfo['immuno_a'] != labInfo['immuno_a']: failures.append('Table value: ' + '"' + str(lInfo['immuno_a']) + '"' + ' expected ' + '"' + str(labInfo['immuno_a']) + '"') if lInfo['immuno_m'] != labInfo['immuno_m']: failures.append('Table value: ' + '"' + str(lInfo['immuno_m']) + '"' + ' expected ' + '"' + str(labInfo['immuno_m']) + '"') if lInfo['platelets'] != labInfo['platelets']: failures.append('Table value: ' + '"' + str(lInfo['platelets']) + '"' + ' expected ' + '"' + str(labInfo['platelets']) + '"') if self.add_new_labs.text != 'Add New Labs': failures.append('AddLabsView: Unexpected add new labs button text') if len(failures) > 0: for failure in failures: print(failure) return False return True def load_table(self): # Table with saved Lab results at bottom of page # Read info from each row and return dictionary self.clinical_tables = [] # Table Header try: table_header = self.form.find_element_by_class_name( 'sticky-table-header-wrapper') except NoSuchElementException: # No lab results saved (or table not displayed yet) return None header_cells = table_header.find_elements_by_class_name( 'sticky-table-cell') header_keys = [ 'actions', 'dobd', 'monoclonal', 'kappa', 'lambda', 'ratio', 'bone_marrow', 'creatine', 'platelets', 'neutrophils', 'blood_cell', 'hemoglobin', 'lactate', 'albumin', 'immuno_g', 'immuno_a', 'immuno_m', 'calcium' ] # Table Body table_body = self.form.find_element_by_class_name( 'sticky-table-y-wrapper') # Actions, Lab date stationary_content = table_body.find_element_by_class_name( 'sticky-table-table') stationary_rows = stationary_content.find_elements_by_class_name( 'sticky-table-row') # self.clinical_tables.append({'delete': stationary_rows[0].find_element_by_class_name('delete')}) # Lab fields sliding_content = table_body.find_element_by_class_name( 'sticky-table-x-wrapper') sliding_rows = sliding_content.find_elements_by_class_name( 'sticky-table-row') for rowIndex, row in enumerate(stationary_rows): # print(rowIndex) rowInfo = {} # Info for an individual lab result stationary_row = row rowInfo['edit'] = stationary_row.find_element_by_class_name('edit') rowInfo['delete'] = stationary_row.find_element_by_class_name( 'delete') rowInfo['date'] = stationary_row.find_elements_by_class_name( 'sticky-table-cell')[1].text sliding_row = sliding_rows[rowIndex] cells = sliding_row.find_elements_by_class_name( 'sticky-table-cell') if rowIndex < 5: print(len(cells)) for cellIndex, cell in enumerate(cells): rowInfo[header_keys[cellIndex]] = cell.text.lower() if rowInfo: self.clinical_tables.append(rowInfo) def get_my_labs(self): self.add_new_labs.click() self.addLabsForm = addLabsForm.AddLabsForm(self.driver) WDW(self.driver, 10).until(lambda x: self.addLabsForm.load()) self.util.click_el(self.addLabsForm.get_my_labs_button ) # Should now be on /my-labs-facilities def add_new_lab(self, labInfo, action='save'): self.add_new_labs.click() self.addLabsForm = addLabsForm.AddLabsForm(self.driver) WDW(self.driver, 10).until(lambda x: self.addLabsForm.load()) self.addLabsForm.submit(labInfo, 'save') WDW(self.driver, 3).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-dialog'))) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) def edit_delete_lab(self, testIndex=0, revisedLabInfo=None, action='delete', popUpAction='confirm'): try: test = self.clinical_tables[testIndex] except IndexError: print('No test w/ index: ' + str(testIndex)) return False if test: if action == 'delete': test['delete'].click() self.popUpForm = popUpForm.PopUpForm(self.driver) WDW(self.driver, 10).until(lambda x: self.popUpForm.load()) self.popUpForm.confirm(popUpAction) else: test['edit'].click() WDW(self.driver, 10).until(lambda x: self.addLabsForm.load()) self.addLabsForm.submit(revisedLabInfo, 'save') return True def delete_all_labs(self): while self.clinical_tables: self.edit_delete_lab() time.sleep(2) self.load()
class MyelomaGeneticsView(view.View): post_url = 'myeloma-genetics' def load(self, riskInfo=None): self.util = UtilityFunctions(self.driver) try: WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.menu = menu.Menu(self.driver) self.header = header.AuthHeader(self.driver) self.load_test_table() # When user has already filled out info # addDiagnosisButtons = self.driver.find_elements_by_class_name('addDiagnoisisButton') # self.add_fish_button = addDiagnosisButtons[0] # self.add_gep_button = addDiagnosisButtons[1] # self.add_ngs_button = addDiagnosisButtons[2] # buttons = self.driver.find_elements_by_tag_name('button') # self.upload_file_button = buttons[2] # cont = self.driver.find_element_by_class_name('genetics-btn') # self.continue_button = cont.find_element_by_tag_name('button') # # self.load_fish_table() # # self.load_gep_table() # # self.load_ngs_table() # # self.load_highRisk_table() # self.container = self.driver.find_element_by_id('page-content-wrapper') # tooltips = self.container.find_elements_by_tag_name('img') # self.fish_tooltip = tooltips[0] # self.gep_tooltip = tooltips[1] # self.ngs_tooltip = tooltips[2] # self.high_risk_tooltip = tooltips[3] # When user hasn't filled anything out # todo return True except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False def load_fish_table(self): self.fish_tests = [] fishTable = '' try: fishTable = self.driver.find_element_by_id('fish_table') rows = fishTable.find_elements_by_class_name('table_row') except NoSuchElementException: pass labInfo = [] # add text from each header row to values list if fishTable: for rowIndex, row in enumerate(rows): labResult = {} divs = row.find_elements_by_tag_name('div') tds = row.find_elements_by_tag_name('td') # for divIndex, div in enumerate(divs): for tdIndex, td in enumerate(tds): if rowIndex == 0: labInfo.append(td.text.lower()) else: key = labInfo[tdIndex] if key.lower() == 'actions': actions = [] self.edit_button = row.find_element_by_class_name( 'edit-treatment-icon') self.delete_button = row.find_element_by_class_name( 'delete-treatment-icon') actions.append(self.edit_button) actions.append(self.delete_button) labResult[key] = actions else: text = td.text labResult[key] = text self.fish_tests.append(labResult) def load_gep_table(self): self.gep_tests = [] gepTable = '' try: gepTable = self.driver.find_element_by_id('gep_table') except NoSuchElementException: pass if gepTable: rows = gepTable.find_elements_by_class_name('table_row') labInfo = [] # add text from each header row to values list for rowIndex, row in enumerate(rows): labResult = {} divs = row.find_elements_by_tag_name('div') tds = row.find_elements_by_tag_name('td') # for divIndex, div in enumerate(divs): for tdIndex, td in enumerate(tds): if rowIndex == 0: labInfo.append(td.text.lower()) else: key = labInfo[tdIndex] if key.lower() == 'actions': actions = [] self.edit_button = row.find_element_by_class_name( 'edit-treatment-icon') self.delete_button = row.find_element_by_class_name( 'delete-treatment-icon') actions.append(self.edit_button) actions.append(self.delete_button) labResult[key] = actions else: text = td.text labResult[key] = text if labResult: self.gep_tests.append(labResult) def load_ngs_table(self): self.ngs_tests = [] ngsTable = '' try: ngsTable = self.driver.find_element_by_id('ngs_table') rows = ngsTable.find_elements_by_class_name('table_row') except NoSuchElementException: pass labInfo = [] # add text from each header row to values list if ngsTable: for rowIndex, row in enumerate(rows): labResult = {} tds = row.find_elements_by_tag_name('td') # for divIndex, div in enumerate(divs): for tdIndex, td in enumerate(tds): if rowIndex == 0: labInfo.append(td.text.lower()) else: key = labInfo[tdIndex] if key.lower() == 'actions': actions = [] self.edit_button = row.find_element_by_class_name( 'edit-treatment-icon') self.delete_button = row.find_element_by_class_name( 'delete-treatment-icon') actions.append(self.edit_button) actions.append(self.delete_button) labResult[key] = actions else: text = td.text labResult[key] = text self.ngs_tests.append(labResult) def load_highRisk_table(self): self.highRiskTable = self.driver.find_element_by_id('yesno_table') rows = self.highRiskTable.find_elements_by_class_name('table_row') labInfo = [] self.highRisk_tests = {} self.highRisk_tests[ 'edit'] = self.highRiskTable.find_element_by_class_name( 'edit-treatment-icon') # {'High Beta-2 Microglobulin': 'Yes', # 'High Lactate Dehydrogenase': 'I dont know', # 'Low albumin': 'I dont know', # 'edit': webElement, # } for i, row in enumerate(rows): if i > 0 and i < 4: tds = row.find_elements_by_tag_name('td') for tdIndex, td in enumerate(tds): if tdIndex == 0: name = td.text else: value = td.text self.highRisk_tests[name] = value def validate_gep_test(self, gepInfo): failures = [] if len(self.gep_tests) > 0: loadedInfo = self.gep_tests[-1] else: loadedInfo = self.gep_tests if loadedInfo: if self.convert_date( loadedInfo['date'].lower()) != gepInfo['test_gep_date']: failures.append( 'GEP Table: Expecting ' + '"' + str(gepInfo['test_gep_date']) + '"' + ', got ' + '"' + str(self.convert_date(loadedInfo['date'].lower())) + '"') if loadedInfo['comment'] != gepInfo['gep_comment']: failures.append('GEP Table: Expecting ' + '"' + str(gepInfo['gep_comment']) + '"' + ', got ' + '"' + str(loadedInfo['comment']) + '"') if len(failures) > 0: for failure in failures: print(failure) raise NoSuchElementException( 'Failed to load myelomaGeneticsView') else: pass def validate_risk_table(self, riskInfo): failures = [] if riskInfo: rows = self.highRiskTable.find_elements_by_class_name('table_row') for i, row in enumerate(rows): tds = row.find_elements_by_tag_name('td') if i == 0: if tds[0].text != 'Test': failures.append( 'High Risk Table: Expecting text "Test", got ' + '"' + str(tds[0].text) + '"') if tds[1].text != 'Answer': failures.append( 'High Risk Table: Expecting text "Answer", got ' + '"' + str(tds[1].text) + '"') if i == 1: if tds[0].text != 'High Beta-2 Microglobulin': failures.append( 'High Risk Table: Expecting text "High Beta-2 Microglobulin", got' + '"' + str(tds[0].text) + '"') if tds[1].text.replace("'", '') != riskInfo['high_b2m']: failures.append('High Risk Table: Expecting text ' + '"' + str(riskInfo['high_b2m']) + '"' + ' got ' + '"' + str(tds[1].text) + '"') if i == 2: if tds[0].text != 'High Lactate Dehydrogenase': failures.append( 'High Risk Table: Expecting text "High Lactate Dehydrogenase", got' + '"' + str(tds[0].text) + '"') if tds[1].text.replace("'", '') != riskInfo['high_ldh']: failures.append('High Risk Table: Expecting text ' + '"' + str(riskInfo['high_ldh']) + '"' + ' got ' + '"' + str(tds[1].text) + '"') if i == 3: if tds[0].text != 'Low albumin': failures.append( 'High Risk Table: Expecting text "Low albumin", got ' + '"' + str(tds[0].text) + '"') if tds[1].text.replace("'", '') != riskInfo['low_albumin']: failures.append('High Risk Table: Expecting text ' + '"' + str(riskInfo['low_albumin']) + '"' + ' got ' + '"' + str(tds[1].text) + '"') if len(failures) > 0: for failure in failures: print(failure) raise NoSuchElementException( 'Failed to load myelomaGeneticsView') def add_fish_test(self, fishInfo, action='save'): self.add_fish_button.click() self.fishTestForm = fishTestForm.FishTestForm(self.driver) WDW(self.driver, 10).until(lambda x: self.fishTestForm.load()) self.fishTestForm.submit(fishInfo, action) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-dialog'))) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) def add_gep_test(self, gepInfo, action='cancel'): self.add_gep_button.click() self.gepTestForm = gepTestForm.GepTestForm(self.driver) WDW(self.driver, 10).until(lambda x: self.gepTestForm.load()) self.gepTestForm.submit(gepInfo, action) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-dialog'))) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.load() self.validate_gep_test(gepInfo) def add_ngs_test(self, ngsInfo, action='save'): self.add_ngs_button.click() self.ngsTestForm = ngsTestForm.NgsTestForm(self.driver) WDW(self.driver, 10).until(lambda x: self.ngsTestForm.load()) self.ngsTestForm.submit(ngsInfo, action) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-dialog'))) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) def edit_test(self, testType, testIndex, testValues, action='delete', popUpAction='confirm'): test = self.get_test(testType, testIndex) if testType == 'fish': if action == 'edit': test['actions'][0].click() else: test['actions'][1].click() self.popUpForm = popUpForm.PopUpForm(self.driver) WDW(self.driver, 10).until(lambda x: self.popUpForm.load()) self.popUpForm.confirm(popUpAction) elif testType == 'gep': if action == 'edit': test['actions'][0].click() else: test['actions'][1].click() self.popUpForm = popUpForm.PopUpForm(self.driver) WDW(self.driver, 10).until(lambda x: self.popUpForm.load()) self.popUpForm.confirm(popUpAction) elif testType == 'ngs': if action == 'edit': test['actions'][0].click() else: test['actions'][1].click() self.popUpForm = popUpForm.PopUpForm(self.driver) WDW(self.driver, 10).until(lambda x: self.popUpForm.load()) self.popUpForm.confirm(popUpAction) else: if action == 'edit': self.highRisk_tests['edit'].click() self.edit_high_risk(testValues, 'save') else: print('Error: Edit High Risk Test action not possible') WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-dialog'))) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) def edit_high_risk(self, riskInfo, action='save'): self.editHighRiskForm = editHighRiskForm.EditHighRiskForm(self.driver) WDW(self.driver, 10).until(lambda x: self.editHighRiskForm.load()) self.editHighRiskForm.submit(riskInfo, action) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-dialog'))) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) self.validate_risk_table(riskInfo) def upload_file(self, action='cancel'): self.upload_file_button.click() self.uploadFileForm = uploadFileForm.UploadFileForm(self.driver) WDW(self.driver, 10).until(lambda x: self.uploadFileForm.load()) self.uploadFileForm.confirm(action) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'modal-dialog'))) WDW(self.driver, 10).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) def get_test(self, testType, testIndex): if testType == 'fish': return self.fish_tests[testIndex] elif testType == 'gep': return self.gep_tests[testIndex] elif testType == 'ngs': return self.ngs_tests[testIndex] else: return self.highRisk_tests def tooltip(self): p = self.container.find_elements_by_class_name('tooltip-p') index = p[0].text.find(' ') if p[0].text[:index] != 'FISH': return False if self.util.get_text( p[1] ) != 'Gene Expression Profiling (GEP) is the measurement of the activity, or expression, of thousands of genes at once. This test can help identify standard risk and high risk genomic features of the myeloma cells in more depth.': print('tooltip not clicked correctly: ' + str(self.util.get_text(p[1]))) return False if self.util.get_text( p[2] ) != 'Next Generation Sequencing looks at the myeloma DNA and RNA and identifies how the mutations are functioning, how the myeloma cells are evolving and how your myeloma may respond to treatment. Currently, NGS testing is typically performed at myeloma academic centers only.': print('tooltip not clicked correctly: ' + str(self.util.get_text(p[2]))) return False if self.util.get_text( p[3] ) != 'Risk in myeloma is tied to disease stage, chromosomal abnormalities, disease biology, and gene expression. In the Myeloma Genetics page we will gather more details about risk.': print('tooltip not clicked correctly: ' + str(self.util.get_text(p[3]))) return False return True def convert_date(self, dateStr): # Input: 'mmm yyyy', Output; 'mm/yyyy' spaceIndex = dateStr.find(' ') # Should always be 3 if spaceIndex == 3: months = [ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ] monthName = dateStr[:3] year = dateStr[4:] month = str(months.index(monthName) + 1).zfill(2) return month + '/' + str(year) else: if dateStr != 'current treatment': print('Unexpected date format: ' + str(dateStr)) return dateStr def load_test_table(self): self.genetic_tests = [] tables = self.driver.find_elements_by_class_name('divTable') for tableIndex, table in enumerate(tables): rows = table.find_elements_by_class_name('divTableRow') if tableIndex == 0: for rowIndex, row in enumerate(rows): cells = row.find_elements_by_class_name('divTableCell') if rowIndex == 0: self.headerInfo = [] for cell in cells: self.headerInfo.append(cell.text)
class ForgotPwView(view.View): post_url = 'forgot-password' def load(self): self.util = UtilityFunctions(self.driver) try: # Crap on left self.forgotPwForm = forgotPwForm.ForgotPwForm(self.driver) self.signIn_link = self.driver.find_elements_by_tag_name('a')[-1] self.validate() return True except (NoSuchElementException, StaleElementReferenceException, IndexError) as e: return False def validate(self): failures = [] if self.util.get_text(self.signIn_link) != 'Sign In': failures.append( '1. Sign In link. Expecting text "Sign In", got "' + self.util.get_text(self.signIn_link) + '"') if len(failures) > 0: print(failures) raise NoSuchElementException('Failed to load HomeView') def createErrorObj(self, errorText): errorType = 'undefined' errorMsg = '' if 'confirm your email address' in errorText: errorType = 'confirmation' errorMsg = 'homeView.login: Confirmation error' elif 'invalid username or password' in errorText: errorType = 'invalid credentials' errorMsg = 'homeView.login: Invalid Credentials error' return { 'text': errorText, 'type': errorType, 'msg': errorMsg, } def reset_password(self, email, expectedErrorType=None, expectedWarning=None): try: if self.forgotPwForm.submit_form(email): # Should be on home page url = self.driver.current_url if '/about-me' not in url: # Didn't end up on right page self.error = self.readErrors() self.warning = self.forgotPwForm.read_warning() if self.error: raise MsgError('Login Error') elif self.warning: raise WarningError('Login Warning') return True except MsgError: # Is login expected to fail? errorType = self.error['type'] if expectedErrorType and errorType.lower( ) != expectedErrorType.lower(): print(self.error['msg']) if errorType == 'undefined': print('Undefined error: ' + self.error['text']) else: return True except WarningError: # Is pw reset form expected to have warning? warningType = self.warning['type'] if expectedWarning and warningType.lower( ) != expectedWarning.lower(): print(self.warning['msg']) if warningType == 'undefined': print('Undefined warning: ' + self.warning['text']) else: return True return False def click_link(self, link): if link == 'sign in': self.signIn_link.click()
class VaccinationsSurveyForm(): def __init__(self, driver): self.driver = driver self.util = UtilityFunctions(self.driver) def load(self): WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) time.sleep(1) self.form = self.driver.find_elements_by_tag_name('form')[1] buttons = self.form.find_elements_by_tag_name('button') self.close_button = buttons[0] self.save_button = buttons[1] self.cancel_button = buttons[2] self.load_form() self.loadedData = self.questionList return True def load_form(self): self.questionContainers = self.form.find_elements_by_class_name( 'ques_group_cls') self.subQuestionIndices = [] self.questionList = [] for questionIndex, questionContainer in enumerate( self.questionContainers): # print('loading question: ' + str(questionIndex)) # Primary or secondary question? subquestions = questionContainer.find_elements_by_class_name( 'ques_group_cls') if len(subquestions) > 0: for subquestionIndex in xrange(len(subquestions)): subIndex = questionIndex + 1 + subquestionIndex print('subquestion: ' + str(subIndex)) self.subQuestionIndices.append(subIndex) if questionIndex not in self.subQuestionIndices: # Primary question self.questionList.append( self.load_questions(questionContainer)) def load_questions(self, questionContainer, isSecondary=False): question = {} questionIndex = None # First is primary. Any additional ones are secondary questionConts = questionContainer.find_elements_by_class_name( 'question') if isSecondary: questionConts = [questionContainer] for i, questionCont in enumerate(questionConts): # print('loading questionCont: ' + str(i)) textInput = None radioOptions = None options = {} secondary_questions = [] if i == 0: # Primary try: # look for radio options radioContainers = questionCont.find_elements_by_class_name( 'dynamic-radio') for radioCont in radioContainers: inputs = radioCont.find_elements_by_tag_name('input') spans = radioCont.find_elements_by_tag_name('span') optionName = self.util.get_text(spans[0]).lower() options[optionName] = inputs[0] if len(radioContainers) == 0: textInput = questionCont.find_element_by_tag_name( 'input') except NoSuchElementException: pass # Look for an input else: # secondary # Some 'question' elements don't have questions if len(questionCont.find_elements_by_tag_name('input')) > 0: # print('loading secondary question: ' + str(i)) secondary_questions.append( self.load_questions(questionCont, True)) question['container'] = questionCont if options: question['options'] = options if textInput: question['textInput'] = textInput if secondary_questions: question['secondary_questions'] = secondary_questions # print('returning: ' + str(question)) return question def submit(self, mrdInfo, action='cancel'): for questionIndex, question in enumerate(mrdInfo): print('answering question: ' + str(questionIndex)) loadedQuestion = self.loadedData[questionIndex] secondaryInfo = question.get('secondary', None) questionOptions = loadedQuestion.get('options', None) textarea = loadedQuestion.get('textInput', None) dropdowns = loadedQuestion.get('dropdowns', None) multipleDropdown = question.get('multiple_dropdown') if questionOptions: WDW(self.driver, 20).until_not( EC.presence_of_element_located((By.CLASS_NAME, 'overlay'))) inputEl = questionOptions[question['option']] inputEl.click() if not inputEl.is_selected(): print('Clicked input, but it is not selected') return False if textarea: textarea.send_keys(question.get('textInput', None)) if dropdowns: if multipleDropdown: self.form.set_dropdown( dropdowns[0], question.get('multiple_dropdown', None)) AC(self.driver).send_keys(Keys.ESCAPE).perform() else: self.form.set_dropdown(dropdowns[0], question.get('dropdown', None)) if secondaryInfo: # Question has secondary response # Reload question and get loadedInfo for secondary question WDW(self.driver, 20).until(lambda x: self.load()) loadedSecondaryInfo = self.loadedData[questionIndex].get( 'secondary_questions', None) secondaryText = secondaryInfo.get('text', None) secondaryOptions = secondaryInfo.get('options', None) if secondaryText: print(loadedSecondaryInfo) textInput = loadedSecondaryInfo[0]['textInput'] if textInput: textInput.clear() textInput.send_keys(secondaryText) else: print('could not find textarea for question[' + str(questionIndex) + ']') else: radioOptions = loadedSecondaryInfo[0]['options'] radioOptions[secondaryOptions].click() time.sleep(1) if action == 'save': self.save_button.click() else: self.cancel_button.click() return True
def __init__(self, driver, expectedValues=None): self.driver = driver self.util = UtilityFunctions(self.driver) self.load(expectedValues)
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