Utils.py 11 KB

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