Utils.py 10 KB

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