Utils.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. from datetime import datetime
  2. import baangt.base.GlobalConstants as GC
  3. import baangt.base.CustGlobalConstants as CGC
  4. import inspect
  5. import ntpath
  6. import logging
  7. import json
  8. import sys
  9. import traceback
  10. from pathlib import Path
  11. from baangt.base.PathManagement import ManagedPaths
  12. logger = logging.getLogger("pyC")
  13. class utils:
  14. def __init__(self):
  15. self.__perf_trace = {}
  16. @staticmethod
  17. def datetime_return():
  18. # needed, so that the datetime-module is called newly
  19. t = datetime.now().strftime("%Y%m%d_%H%M%S")
  20. return t
  21. @staticmethod
  22. def extractFileNameFromFullPath(fileAndPathName):
  23. return ntpath.basename(fileAndPathName)
  24. @staticmethod
  25. def sanitizeFileName(value):
  26. value = value.replace("'", "")
  27. value = value.replace('"', "")
  28. return value
  29. @staticmethod
  30. def replaceFieldValueWithValueOfConstant(value):
  31. """
  32. If a String reference to global Constant (e.g. GC.BROWSER_FF) is
  33. given, this function will replace it with the actual value (e.g. FIREFOX)
  34. """
  35. if value[0:3] == "GC." or value[0:4] == 'CGC.':
  36. if value[0:3] == 'GC.':
  37. try:
  38. value = getattr(globals()[value.split(".")[0]], value.split(".")[1])
  39. except Exception as e:
  40. logger.warning(f"Referenced variable doesn't exist: {value}")
  41. elif value[0:4] == 'CGC.':
  42. value = getattr(globals()[value.split(".")[0]], value.split(".")[1])
  43. return value
  44. @staticmethod
  45. def replaceAllGlobalConstantsInDict(lDict: dict):
  46. lDictOut = {}
  47. for key, value in lDict.items():
  48. lKey = utils.replaceFieldValueWithValueOfConstant(key)
  49. if isinstance(value, str):
  50. lDictOut[lKey] = utils.replaceFieldValueWithValueOfConstant(value)
  51. elif isinstance(value, dict):
  52. lDictOut[lKey] = utils.replaceAllGlobalConstantsInDict(value)
  53. elif isinstance(value, list):
  54. lDictOut[lKey] = utils._loopList(value)
  55. else:
  56. lDictOut[lKey] = value
  57. return lDictOut
  58. @staticmethod
  59. def traceback(exception_in):
  60. ex_traceback = exception_in.__traceback__
  61. tb_lines = "\n".join([line.rstrip('\n') for line in
  62. traceback.format_exception(exception_in.__class__, exception_in, ex_traceback)])
  63. logger.info(tb_lines)
  64. @staticmethod
  65. def _loopList(listIn):
  66. listOut = []
  67. for item in listIn:
  68. if isinstance(item, str):
  69. item = utils.replaceFieldValueWithValueOfConstant(item)
  70. elif isinstance(item, dict):
  71. item = utils.replaceAllGlobalConstantsInDict(item)
  72. elif isinstance(item, list):
  73. item = utils._loopList(item)
  74. listOut.append(item)
  75. return listOut
  76. @staticmethod
  77. def openJson(fileNameAndPath):
  78. logger.info(f"Reading Definition from {fileNameAndPath}")
  79. data = None
  80. fileNameAndPath = utils.findFileAndPathFromPath(fileNameAndPath)
  81. with open(fileNameAndPath) as json_file:
  82. data = json.load(json_file)
  83. return data
  84. @staticmethod
  85. def setLogLevel(level):
  86. logger.info(f"Changing Loglevel from {logger.level} to {level}")
  87. for logHandler in logger.handlers:
  88. logHandler.setLevel(level=level.upper())
  89. logger.setLevel(level=level.upper())
  90. @staticmethod
  91. def listToString(completeList):
  92. """
  93. Returns a concatenated string from a list-object
  94. :param completeList: any List
  95. :return: String
  96. """
  97. if len(completeList) > 0:
  98. returnString = utils.__listChildToString(completeList)
  99. returnString = returnString.lstrip("\n")
  100. return returnString
  101. @staticmethod
  102. def __listChildToString(listEntry):
  103. """
  104. Recursively going through a dict and transforming each layer into a string.
  105. :param listEntry:
  106. :return:
  107. """
  108. returnString = ""
  109. for entry in listEntry:
  110. if isinstance(entry, list):
  111. returnString = f"{returnString}\n{utils.__listChildToString(entry)}"
  112. else:
  113. returnString = f"{returnString}, {entry}"
  114. returnString = returnString.lstrip(", ")
  115. return returnString
  116. @staticmethod
  117. def setLocatorFromLocatorType(lLocatorType, lLocator):
  118. """
  119. @param lLocatorType: XPATH, CSS, ID, etc.
  120. @param lLocator: Value of the locator
  121. @return:
  122. """
  123. xpath = None
  124. css = None
  125. lId = None
  126. if lLocatorType:
  127. if lLocatorType == 'XPATH':
  128. xpath = lLocator
  129. elif lLocatorType == 'CSS':
  130. css = lLocator
  131. elif lLocatorType == 'ID':
  132. lId = lLocator
  133. return xpath, css, lId
  134. @staticmethod
  135. def dynamicImportOfClasses(modulePath=None, className=None, fullQualifiedImportName=None):
  136. """
  137. Will import a class from a module and return the class reference
  138. @param fullQualifiedImportName: Full name of Module and Class. Alternatively:
  139. @param modulePath: Path to module and:
  140. @param className: Name of the class inside the module
  141. @return: The class instance. If no class instance can be found the TestRun aborts hard with sys.exit
  142. """
  143. if fullQualifiedImportName:
  144. moduleToImport = ".".join(fullQualifiedImportName.split(".")[0:-1])
  145. importClass = fullQualifiedImportName.split(".")[-1]
  146. else:
  147. importClass = className
  148. moduleToImport = modulePath
  149. # The above works well for classes "franzi" and "baangt.base.franzi". Not for ".franzi"
  150. if not moduleToImport:
  151. moduleToImport = importClass
  152. if globals().get(importClass):
  153. # FIXME: Here he seems to return the module instead of the class.
  154. x = 1 # This never happened ever. The breakpoint didn't ever halt.
  155. return getattr(globals()[importClass], importClass) # Class already imported
  156. try:
  157. mod = __import__(moduleToImport, fromlist=importClass)
  158. logger.debug(f"Imported class {moduleToImport}.{importClass}, result was {str(mod)}")
  159. retClass = getattr(mod, importClass)
  160. except AttributeError as e:
  161. logger.debug("Import didn't work. Trying something else:")
  162. # This was not successful. Try again with adding the class-name to the Module
  163. mod = __import__(moduleToImport + "." + importClass, fromlist=importClass)
  164. logger.debug(f"Imported class {moduleToImport}.{importClass}.{importClass}, result was {str(mod)}")
  165. retClass = getattr(mod, importClass)
  166. # If this is a class, all is good.
  167. if inspect.isclass(retClass):
  168. pass
  169. else:
  170. # Try to find the class within the module:
  171. for name, obj in inspect.getmembers(retClass):
  172. if name == importClass:
  173. retClass = getattr(retClass, importClass)
  174. return retClass
  175. if not retClass:
  176. logger.critical(f"Can't import module: {modulePath}.{moduleToImport}")
  177. sys.exit("Critical Error in Class import - can't continue. "
  178. "Please maintain proper classnames in Testrundefinition.")
  179. return retClass
  180. @staticmethod
  181. def findFileAndPathFromPath(fileNameAndPath, basePath=None):
  182. """
  183. Tries different approaches to locate a file
  184. lBasePath = the Path where the script is run
  185. @param fileNameAndPath: Filename and potentially relative path
  186. @param basePath (optional): Optional basePath to look at
  187. @return:
  188. """
  189. lFileNameAndPath = fileNameAndPath
  190. if basePath:
  191. lBasePath = Path(basePath)
  192. if "~" in str(lBasePath):
  193. lBasePath = lBasePath.expanduser()
  194. else:
  195. lBasePath = Path(sys.argv[0]).parent # Works in Windows
  196. logger.debug(f"Main Path to search for files: {lBasePath}")
  197. if len(str(lBasePath)) < 3:
  198. # Most probaby we're in pyinstaller. Let's try to find executable path
  199. lBasePath = Path(sys.executable).parent
  200. logger.debug(f"New Main Path to search for files: {lBasePath}")
  201. if not Path(lFileNameAndPath).exists():
  202. managedPaths = ManagedPaths()
  203. root_dir = managedPaths.getOrSetRootPath()
  204. if "~" in str(lFileNameAndPath):
  205. lFileNameAndPath = Path(lFileNameAndPath).expanduser()
  206. if not lFileNameAndPath.exists():
  207. raise Exception(f"Can't find file {fileNameAndPath}")
  208. elif Path(lBasePath).joinpath(fileNameAndPath).exists():
  209. lFileNameAndPath = Path(lBasePath).joinpath(lFileNameAndPath)
  210. logger.debug(f"Found file via BasePath {str(lFileNameAndPath)}")
  211. elif len(Path(lFileNameAndPath).parents) == 0:
  212. # This is only the filename. Try with current path and a bit up
  213. if Path(utils.__file__).joinpath(lFileNameAndPath).exists():
  214. lFileNameAndPath = Path(utils.__file__).joinpath(lFileNameAndPath)
  215. elif Path(utils.__file__).parent.joinpath(lFileNameAndPath).exists():
  216. lFileNameAndPath = Path(utils.__file__).parent.joinpath(lFileNameAndPath)
  217. elif Path(utils.__file__).parent.parent.joinpath(lFileNameAndPath).exists():
  218. lFileNameAndPath = Path(utils.__file__).parent.parent.joinpath(lFileNameAndPath)
  219. elif Path(root_dir).joinpath(lFileNameAndPath).exists():
  220. lFileNameAndPath = Path(root_dir).joinpath(lFileNameAndPath)
  221. elif Path(root_dir).joinpath("baangt").joinpath(lFileNameAndPath).exists():
  222. lFileNameAndPath = Path(root_dir).joinpath("baangt").joinpath(lFileNameAndPath)
  223. elif Path(root_dir).joinpath("baangt").joinpath("base").joinpath(lFileNameAndPath).exists():
  224. lFileNameAndPath = Path(root_dir).joinpath("baangt").joinpath("base").joinpath(lFileNameAndPath)
  225. else:
  226. raise Exception(f"Can't find file {fileNameAndPath}")
  227. else:
  228. raise Exception(f"Can't find file {fileNameAndPath}")
  229. else:
  230. lFileNameAndPath = Path(lFileNameAndPath)
  231. return str(lFileNameAndPath.absolute())
  232. @staticmethod
  233. def anything2Boolean(valueIn):
  234. if isinstance(valueIn, bool):
  235. return valueIn
  236. if isinstance(valueIn, int):
  237. return bool(valueIn)
  238. if isinstance(valueIn, str):
  239. if valueIn.lower() in ("yes", "true", "1", "ok", "x"):
  240. return True
  241. else:
  242. return False
  243. if not valueIn:
  244. return False
  245. raise TypeError(f"Anything2Boolean had a wrong value: {valueIn}. Don't know how to convert that to boolean")