Beispiel #1
0
class CurrentHealthForm():

	def __init__(self, driver, expectedValues=None):
		self.driver = driver
		self.util = UtilityFunctions(self.driver)
		self.load(expectedValues)

	def load(self, expectedValues):

		WDW(self.driver, 10).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay')))
		self.form = self.driver.find_elements_by_tag_name('form')[-1]
		inputs = self.form.find_elements_by_tag_name('input')
		self.question_elements = self.form.find_elements_by_class_name('custom-current-health')
		self.questions = []
		for i, question in enumerate(self.question_elements):
			self.load_question(self.question_elements[i])

		tooltips = self.form.find_elements_by_tag_name('img')
		self.blood_pressure_tooltip = tooltips[0]
		self.blood_clot_tooltip = tooltips[1]
		self.neuropathy_tooltip = tooltips[2]

		self.continue_button = self.form.find_element_by_class_name('submitForm')
		self.validate(expectedValues)
		return True

	def load_question(self, container):
		# Load question title (label), value, and any secondary questions and their values
		labels = container.find_elements_by_tag_name('label')
		question_label = self.util.get_text(labels[0])
		value = None
		secondaryQuestions = []

		# Value: None if not set
		options = ['yes', 'no', 'dont know']
		for i, label in enumerate(labels):
			if i > 0 and i < 4:
				classes = label.get_attribute('class')
				if 'active' in classes:
				 	value = options[i - 1]
		# Find secondary questions
		if value == 'yes':
			secondary_container = container.find_element_by_class_name('custom-history_label')
			secondary_questions = container.find_elements_by_class_name('form-check')

			for secondary_question in secondary_questions:
				secondary_label = self.util.get_text(secondary_question)
				secondary_input = secondary_question.find_element_by_tag_name('input')

				selected = secondary_input.is_selected()

				secondaryQuestions.append({secondary_label: selected})

		question = {
			'name': question_label,												# name: Kidney Conditions
			'value': value,																# value: 'yes'
			'secondaryQuestions': secondaryQuestions, 		# secondaryQuesitons: [
		} 																								# {'Mild kidney problems (renal impairment)': False},
		self.questions.append(question)										# {'Severe kidney problems or on dialysis': False},]

	def validate(self, expectedValues):
		failures = []
		if expectedValues:

			# meta validation
			try:
				meta_validators = expectedValues['meta']
				for key, value in meta_validators.iteritems():
					if key == 'num_questions' and value != len(self.questions):
						failures.append('CurrentHealthForm Meta: Expected ' + str(value) + ' questions. Form has ' + str(len(self.questions)))
			except KeyError:
				# No meta validation
				pass

			# Form validation
			# expectedValues should be dictionary containing {'questions': []}
			expectedQuestions = None
			try:
				expectedQuestions = expectedValues['questions']
			except KeyError:
				# No form validation
				pass
			if expectedQuestions:
				# Check # of questions match
				if len(expectedQuestions) != len(self.questions):
					failures.append('CurrentHealthForm: Expecting ' + str(len(expectedQuestions)) + ' questions. Loaded '
						+ str(len(self.questions)))
				else:
					# Each key in each expectedQuestion (secondaryQuestions, name, value) should exist in loadedQuestion and match it's value
					for i, expectedQuestion in enumerate(expectedQuestions):
						loadedQuestion = self.questions[i]
						# print('comparing ' + str(i) + ': ' + str(expectedQuestion))
						# print('with ' + str(loadedQuestion))
						# raw_input('?')
						for key, expectedValue in expectedQuestion.iteritems():
							try:
								if loadedQuestion[key] != expectedValue:
									failures.append('CurrentHealthForm: Question ' + str(i) + ' expected value "'
										+ expectedValue + '". Loaded "' + loadedQuestion[key] + '"')
							except (TypeError, KeyError) as e:
								# raw_input(str(self.questions[i]))
								failures.append('CurrentHealthForm: Expected Key "' + key + '". Not found in question ' + str(i))

		if len(failures) > 0:
			for failure in failures:
				print(failure)
			raise NoSuchElementException('Failed to load CurrentHealthForm')

	def submit(self, questionInfo, action):
		try:
			questionInfo = questionInfo['questions']
		except KeyError:
			pass

		results = []
		for i, question in enumerate(questionInfo):
			print('answering question: ' + str(i))
			results.append(self.answer_question(i, question))

		if action == 'submit':
			self.continue_button.click()
		return True

	def answer_question(self, index, questionInfo):
		container = self.question_elements[index]
		labels = container.find_elements_by_tag_name('label')
		question_label = self.util.get_text(labels[0])
		labelIndex = {'yes': 1, 'no': 2, 'dont know': 3}

		# If right question, set value
		if question_label == questionInfo['name']:
			i = labelIndex[questionInfo['value']]
			labels[i].click()

			# Handle setting any secondary questions
			if questionInfo['value'] == 'yes' and questionInfo['secondaryQuestions']:
				expectedSecondaryInfo = questionInfo['secondaryQuestions']
				secondary_container = container.find_element_by_class_name('custom-history_label')
				secondary_questions = container.find_elements_by_class_name('form-check')

				# Check # of secondary questions
				if len(secondary_questions) != len(questionInfo['secondaryQuestions']):
					print('CurrentHealth question "' + str(index) + '" expects ' + str(len(questionInfo['secondaryQuestions']))
						+ '. Loaded ' + str(len(secondary_questions)))
					return False

				# Set value for each secondary question
				for i, question in enumerate(secondary_questions):
					question_name = self.util.get_text(question)
					input_el = question.find_element_by_tag_name('input')
					print(input_el)

					if input_el.is_selected() != expectedSecondaryInfo[i][question_name]:
						self.util.click_radio(input_el)
					# else:
					# 	print(str(index) + ' already has correct value')

		else:
			print('Index "' + str(index) + '": Expecting ' + question_label + ' to equal ' + questionInfo['name'])
			return False
		return True

	def tooltip(self):
		p = self.form.find_elements_by_class_name('tooltip-p')
		self.blood_pressure_tooltip.click()
		if self.util.get_text(p[0]).lower() != 'blood pressure is the pressure exerted on walls of the blood vessels by circulating blood. along with body temperature, respiratory rate, and pulse rate, blood pressure is one of the four main vital signs monitored by medical professionals.':
			print('tooltip not clicked correctly:' + str(self.util.get_text(p[0]).lower()))
			return False

		self.blood_clot_tooltip.click()
		if self.util.get_text(p[1]).lower() != 'deep vein thrombosis (dvt) occurs when a blood clot (thrombus) forms in one or more of the deep veins in your body, usually in your legs. deep vein thrombosis can cause leg pain or swelling, but also can occur with no symptoms.':
			print('tooltip not clicked correctly:' + str(self.util.get_text(p[1]).lower()))
			return False
			
		self.neuropathy_tooltip.click()
		if self.util.get_text(p[2]).lower() != 'neuropathy is gradual onset of numbness, prickling or tingling in your feet or hands, which can spread upward into your legs and arms.':
			print('tooltip not clicked correctly:' + str(self.util.get_text(p[2]).lower()))
			return False
		return True
class EditTreatmentPopup():

	def __init__(self, driver):
		self.driver = driver
		self.util = UtilityFunctions(self.driver)

	def load(self, expectedValues=None):
		WDW(self.driver, 10).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay')))
		self.container = self.driver.find_element_by_class_name('editroll') # Should only 1 on T&O view
		self.buttons = self.container.find_elements_by_class_name('green-hvr-bounce-to-top')
		return self.validate(expectedValues)

	def validate(self, expectedValues):
		self.failures = []

		# Basic validation
		if len(self.buttons) != 2:
			self.failures.append('editTreatmentPopup: Expected 2 buttons, loaded ' + str(len(self.buttons)))
		if self.util.get_text(self.buttons[0]) != 'CANCEL':
			self.failures.append('editTreatmentPopup: Unexpected text on cancel button: ' + self.util.get_text(self.buttons[0]))
		if self.util.get_text(self.buttons[1]) != 'SAVE':
			self.failures.append('editTreatmentPopup: Unexpected text on save button: ' + self.util.get_text(self.buttons[1]))

		if expectedValues:
			print('editTreatmentPopup: Need to validate expectedValues')

		if len(self.failures) > 0:
			for failure in self.failures:
				print(failure)
			return False
		return True

	def parse_select_all(self, questionInfo, questionCont):
		done = False
		count = 0
		while not done and count < 5:
			try:
				# Select options in specified in optionInfo
				# De-selecting options not contained in optionInfo
				name_checker = ['Severity of the side effects', 'Cost of the treatment', 'Too much travel']
				radios = questionCont.find_elements_by_class_name('radio')
				suboption_filter = [] # Add index of any suboptions radio buttons to this list. Skip over them
				for i, radio in enumerate(radios):
					if i not in suboption_filter:
						inputs = radio.find_elements_by_tag_name('input')
						spans = radio.find_elements_by_tag_name('span')
						if len(inputs) == 0:
							print('EditTreatmentForm: radio option has no inputElements?')
						elif len(spans) == 0:
							print('EditTreatmentForm: radio option has no spanElements?')

						optionName = self.util.get_text(spans[0])
						print('optionName: ' + optionName)
						optionInput = inputs[0]
						optionInfo = questionInfo.get(optionName, False)
						# raw_input('optionInfo: ' + str(optionInfo))
						subOptions = False
						if optionInfo != False: # select input, enter comment, check for subquestions
							if not optionInput.is_selected():
								self.util.click_radio(optionInput)
							self.util.set_input(radio, optionInfo.get('comment', ''))

							# Check for suboptions or select-all
							subOptions = optionInfo.get('options', False)
							if not subOptions:
								subOptions = optionInfo.get('select-all', False)
						else:
							# De-select, clear comment, update inputs (might have hidden subquestions)
							if optionInput.is_selected():
								self.util.click_radio(optionInput)
								self.util.set_input(radio, '')
								inputs = radio.find_elements_by_tag_name('input')

						# Don't iterate over suboptions
						if len(inputs) > 1:
							for inputIndex, inputEl in enumerate(inputs):
								if inputIndex > 0:
									print('skipping ' + str(i + inputIndex))
									suboption_filter.append(i + inputIndex)

						if subOptions: 
								self.parse_select_all(subOptions, radio)
				done = True
			except StaleElementReferenceException:
				print('failed to parse select-all: ' + str(count))
			count += 1
			time.sleep(.2)
		if count == 5:
			print('EditTreatmentPopup: failed to parse select-all')

	def parse_complex(self, complexInfo, questionCont):
		# For questions w/ multiple sections (sideEffects, chemotherapy drugs, medications added/removed)
		# Loop through complexInfo and select given options for each category
		# De-select options not contained in complexInfo

		# Wait for categories to show up
		categories = None
		loaded = False
		count = 0
		while not loaded and count < 5: # Doesn't immediately load
			categories = questionCont.find_elements_by_class_name('col-md-6')
			if categories:
				loaded = True
			else:
				time.sleep(.2)
			count += 1
		
		question = {}
		for i, category in enumerate(categories):
			# Has issues loading category name sometimes.
			# Make sure it's loaded before looking for options
			loadedCategoryName = False
			count = 0
			while not loadedCategoryName and count < 5:
				try:
					categoryName = self.util.get_text(category.find_element_by_class_name('treatment-group'))
					loadedCategoryName = True
				except NoSuchElementException:
					categoryName = None

				if categoryName: # Loaded name! Parse through category options
					categoryOptions = complexInfo.get(categoryName, False)
					options = {}
					for radio in category.find_elements_by_class_name('radio'):

						inputs = radio.find_elements_by_tag_name('input')
						labels = radio.find_elements_by_tag_name('label')
						label = labels[0]							

						optionName = self.util.get_text(label)
						optionInput = label.find_element_by_tag_name('input')
						optionInfo = False
						if categoryOptions:
							optionInfo = categoryOptions.get(optionName, False)
						if optionInfo != False: # select input, enter comment/intensity
							if not optionInput.is_selected():
								self.util.click_radio(optionInput)
							self.util.set_input(radio, optionInfo.get('comment', ''))
							self.set_intensity(radio, optionInfo.get('intensity', None))
						else:
							# De-select, clear comment, update inputs (might have hidden subquestions)
							if optionInput.is_selected():
								self.util.click_radio(optionInput)
								self.util.set_input(radio, '')
								inputs = radio.find_elements_by_tag_name('input')

				else: # Failed to find categoryName
					count += 1
					time.sleep(.2)

		if complexInfo.get('date', None):
			print('complex question has date. Need to set it')

	def set_intensity(self, container, value):
		try:
			sliderEl = container.find_element_by_class_name('rc-slider-handle')
		except NoSuchElementException:
			print('SideEffectsForm: failed to load sliderEl')
		curValue = sliderEl.get_attribute('aria-valuenow')

		# Need to change intensity value?
		if value != curValue:
			xOffset = None # Every time offset doesn't work, increase by 5 and try again
			additionalOffset = 0
			while str(curValue) != str(value) and additionalOffset < 50:
				if curValue != 1: # reset to base position
					AC(self.driver).drag_and_drop_by_offset(sliderEl, -200, 0).perform()

				# Calculate offset
				# Note: monitor and window sizes affect this.
				if xOffset != None:
					# First offset wasn't correct. Increment amount of offset
					additionalOffset += 4
				xOffset = 11*(value - 1) + additionalOffset
				AC(self.driver).drag_and_drop_by_offset(sliderEl, xOffset, 0).perform()
				curValue = sliderEl.get_attribute('aria-valuenow')

	def set_input(self, container, value):
		# Return if able to set value into textarea or input in container.
		try:
			textareaEl = container.find_element_by_tag_name('textarea')
			textareaEl.clear()
			textareaEl.send_keys(value)
			return True
		except NoSuchElementException:

			try:
				inputEl = container.find_element_by_tag_name('input')
				if inputEl.get_attribute('type') == 'text':
					inputEl.clear()
					inputEl.send_keys(value)
				return True
			except NoSuchElementException:
				return False

	def edit_treatment(self, newInfo, popupType, action='save'):
		# Submit info
		if popupType == 'side effects':
			self.parse_complex(newInfo['options'], self.container)
		elif popupType == 'outcomes':
			self.parse_select_all(newInfo['options'], self.container)

		# Save or cancel
		if action == 'save':
			self.util.click_el(self.buttons[1])
		elif action == 'cancel':
			self.util.click_el(self.buttons[0])
		WDW(self.driver, 15).until_not(EC.presence_of_element_located((By.CLASS_NAME, 'overlay')))
		return True