iselenium.py 2.71 KB
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as Wait
from selenium.webdriver.support import expected_conditions as EC
import time

class SeleniumInterface:

	Chrome = "Chrome"
	By = By()
	Keys = Keys()
	Timeout = 0.5
	PageChangeWait = 0.5

	def __init__(self, driverType):
		self.driver = self._getDriver(driverType)

	def _getDriver(self, d):
		if d == SeleniumInterface.Chrome:
			return webdriver.Chrome()
		raise NoSuchDriver(self.driver)

	def get(self, url):
		time.sleep(SeleniumInterface.PageChangeWait)
		self.driver.get(url)

	def find(self, by, lookup, select = "1"):
		return self.findFromElement(self.driver, by, lookup, select)

	def parent(self, element):
		return self.findFromElement(element, SeleniumInterface.By.XPATH, "parent::*")

	def children(self, element):
		return self.findFromElement(element, SeleniumInterface.By.XPATH, "child::*", "1-")

	def findFromElement(self, element, by, lookup, select = "1"):
		self._wait(element, (by, lookup))
		elements = element.find_elements(by, lookup)
		
		array = []
		for selector in select.replace(" ","").split(","):
			array += self._resolve(selector, elements)

		# One element expected
		if "-" not in select and "," not in select:
			return array[0]
		return array


	def write(self, element, keys, clear = True):
		if clear:
			element.clear()

		if type(keys) == list:
			for k in keys:
				self.write(element, k, clear = False)
		
		element.send_keys(keys)
	
	def readInput(self, input):
		return input.get_attribute("value")

	def readElement(self, element):
		return element.get_attribute("innerText")

	def _resolve(self, selector, elements):
		div, rev, answer = selector.split("-"), False, []
		try:
			# Not a range
			if len(div) == 1:
				return [ elements[int(div[0]) - 1] ]

			# Range	
			b = (1 if div[0] == "" else int(div[0]))
			e = (len(elements) if div[1] == "" else int(div[1]))

			if b > e:
				b, e = e, b
				rev = True

			for i in range(b - 1, e):
				if i < 0 or i >= len(elements):
					continue
				answer.append(elements[i])
			
			if rev:
				answer.reverse()

			return answer
		except:
			raise BadInterval(selector)
	
	def _wait(self, fromElement, locator):
		Wait(fromElement, SeleniumInterface.Timeout).until(
			EC.presence_of_all_elements_located(locator)
		)

	def __del__(self):
		self.driver.close()


class NoSuchDriver(Exception):

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

	def __str__(self):
		return f"The driver '{self.driver}' is not supported"

class BadInterval(Exception):

	def __init__(self, interval):
		self.interval = interval

	def __str__(self):
		return f"The interval '{self.interval}' is not valid"