ViewController.swift 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. //
  2. // ViewController.swift
  3. // KdanAuto
  4. //
  5. // Created by 朱东勇 on 2022/11/17.
  6. //
  7. import Cocoa
  8. import ComPDFKit_Conversion
  9. class ViewController : NSViewController, SettingViewControllerDelegate, AutoTestAdvanceSettingViewDelegate, TestCaseCellViewDelegate,
  10. NSTableViewDelegate, NSTableViewDataSource {
  11. @IBOutlet var customView : NSView!
  12. @IBOutlet var settingVCWindow : NSWindow!
  13. @IBOutlet var settingVC : SettingViewController!
  14. @IBOutlet var itemsList : NSTableView!
  15. var _currentCellInfo : AutoTestCellInfo?
  16. @IBOutlet var advanceView : AutoTestAdvanceSettingView!
  17. @IBOutlet var startBtn : NSButton!
  18. @IBOutlet var replaceAllBtn : NSButton!
  19. @IBOutlet var exportReportBtn : NSButton!
  20. @IBOutlet var advanceBtn : NSButton!
  21. var operateQueue = OperationQueue()
  22. var _isProcessing : Bool!
  23. var _selectFileType : String! = ""
  24. override func viewDidLoad() {
  25. super.viewDidLoad()
  26. customView.wantsLayer = true;
  27. customView.layer?.borderColor = NSColor.lightGray.withAlphaComponent(0.4).cgColor
  28. customView.layer?.borderWidth = 1
  29. advanceView.wantsLayer = true
  30. advanceView.layer?.borderColor = NSColor.lightGray.withAlphaComponent(0.4).cgColor
  31. advanceView.layer?.borderWidth = 1
  32. // Load Infos
  33. let path = Bundle.main.path(forResource: "AutoTestProperty", ofType: "plist")!
  34. let url = URL.init(fileURLWithPath: path, isDirectory: false)
  35. let initInfo = try! NSDictionary.init(contentsOf: url, error: ())
  36. testFileTypes = initInfo.allKeys as [String]
  37. testTypeInfo = initInfo as NSDictionary
  38. //
  39. advanceView.delegate = self;
  40. updateProcessStatus()
  41. self.replaceAllBtn.isEnabled = false;
  42. self.exportReportBtn.isEnabled = false;
  43. DispatchQueue.global().async {
  44. for fileType in testFileTypes {
  45. let types = testTypeInfo[fileType] as! NSArray
  46. for typeInfo in types {
  47. let ti = typeInfo as! NSDictionary
  48. let type = ti["Type"] as! NSString
  49. let testObject = AutoTest.autoTestFor(fileType as NSString, type: type)
  50. if testObject != nil &&
  51. testObject!.canUpdateRefImage() {
  52. DispatchQueue.main.sync {
  53. self.replaceAllBtn.isEnabled = true;
  54. }
  55. break
  56. }
  57. }
  58. }
  59. }
  60. DispatchQueue.main.async {
  61. self.view.window?.title = "KdanAuto:"+CPDFConvertKit.sharedInstance().versionString
  62. }
  63. }
  64. override var representedObject: Any? {
  65. didSet {
  66. // Update the view, if already loaded.
  67. }
  68. }
  69. func reloadListData() {
  70. itemsList.reloadData()
  71. }
  72. // Update
  73. func updateProcessStatus() {
  74. startBtn.wantsLayer = true;
  75. startBtn.layer?.cornerRadius = startBtn.frame.width / 2.0
  76. startBtn.layer?.backgroundColor = NSColor.init(red: 0, green: 0.6, blue: 0.6, alpha: 1).cgColor;
  77. startBtn.contentTintColor = NSColor.white
  78. }
  79. // Setter & Getter
  80. func setCurrentCellInfo(_ cellInfo : AutoTestCellInfo?) {
  81. _currentCellInfo = cellInfo
  82. if (nil != _currentCellInfo) {
  83. let autoTestObj = AutoTest.autoTestFor(NSString(string: (_currentCellInfo?.fileType())!), type:NSString(string: (_currentCellInfo?.typeInfo()["Type"] as! String)))
  84. advanceView.setAutoTestObj(autoTestObj)
  85. }else {
  86. advanceView.setAutoTestObj(nil)
  87. }
  88. }
  89. // IBAction
  90. @IBAction func showSettingVC(_ sender:NSButton) {
  91. let settingVC = SettingViewController.shared()
  92. settingVC.delegate = self
  93. settingVC.show()
  94. }
  95. @IBAction func startAction(_ sender:NSButton) {
  96. let path = DataModel.shared.directoryPath();
  97. if NSString(string: path).isEqual(to: "") || !FileManager.default.fileExists(atPath: path) {
  98. return
  99. }
  100. _isProcessing = true;
  101. updateProcessStatus()
  102. startBtn.isEnabled = false
  103. startBtn.title = "Doing"
  104. exportReportBtn.isEnabled = false;
  105. replaceAllBtn.isEnabled = false;
  106. advanceBtn.isEnabled = false;
  107. DispatchQueue.global().async {
  108. let report = NSMutableAttributedString.init()
  109. // DataModel.shared.generaNewReportID()
  110. TestDegreeManager.shared().clearAllHistory()
  111. let objects = NSMutableArray()
  112. // Update For Waiting
  113. for fileType in testFileTypes {
  114. let types = testTypeInfo[fileType] as! NSArray
  115. for typeInfo in types {
  116. let ti = typeInfo as! NSDictionary
  117. let type = ti["Type"] as! NSString
  118. let testObject = AutoTest.autoTestFor(fileType as NSString, type: type)
  119. testObject?.testlog = { (msg, progress) in
  120. DispatchQueue.main.async {
  121. self.view.window?.title = "\(msg)(\(Int(progress*100))%)";
  122. if (testObject!.isEqual(to: self.advanceView._autoTestObj)) {
  123. self.advanceView.setAutoTestObj(testObject)
  124. }
  125. }
  126. }
  127. if (testObject != nil) {
  128. objects.add(testObject);
  129. }
  130. testObject?.setStatus(.Wait)
  131. }
  132. DispatchQueue.main.sync {
  133. self.reloadListData()
  134. }
  135. }
  136. var objectIndex = 0
  137. var autotestBlock:(NSMutableArray) -> () = { (objects:NSMutableArray) in
  138. }
  139. //创建 Block
  140. autotestBlock = { (objects:NSMutableArray) in
  141. NSLog("Auto Test \(objectIndex)")
  142. if (objectIndex >= objects.count) {
  143. // 所有自动化测试对象均执行完成
  144. do {
  145. let rtfData = try report.data(from: .init(location: 0, length: report.length),
  146. documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf])
  147. let path = DataModel.shared.directoryPath().appendingFormat("/TestReport_\(DataModel.shared.latestReportID()!).rtf")
  148. try rtfData.write(to: NSURL.fileURL(withPath: path))
  149. } catch {
  150. print(error)
  151. }
  152. DispatchQueue.main.async {
  153. self.view.window?.title = "KdanAuto:"+CPDFConvertKit.sharedInstance().versionString
  154. self._isProcessing = false
  155. self.updateProcessStatus()
  156. self.startBtn.isEnabled = true
  157. self.startBtn.title = "Start"
  158. self.replaceAllBtn.isEnabled = true
  159. self.exportReportBtn.isEnabled = true;
  160. self.advanceBtn.isEnabled = true;
  161. TestDegreeManager.shared().saveInfo()
  162. }
  163. return
  164. }
  165. // 执行当前索引自动化测试对象
  166. let testobject = objects.object(at: objectIndex) as! AutoTest
  167. testobject.setStatus(.Process)
  168. // 异步执行自动化测试
  169. testobject.autoTest {(object, inReport) in
  170. if inReport != nil {
  171. // 如果有自动化测试报告,则拼接在后面
  172. report.append(inReport!)
  173. }
  174. DispatchQueue.main.async {
  175. // 更新当前自动化测试对象状态及相关 UI 状态
  176. if (object.needCompareTest()) {
  177. object.setStatus(.Finished)
  178. }else {
  179. object.setStatus(.Normal)
  180. }
  181. self.reloadListData()
  182. if (self.advanceView.getAutoTestObj() != nil &&
  183. object.isEqual(to: self.advanceView.getAutoTestObj())) {
  184. self.advanceView.setAutoTestObj(self.advanceView.getAutoTestObj());
  185. }
  186. }
  187. DispatchQueue.global().async {
  188. autoreleasepool {
  189. // 触发下一个自动化测试对象进入自动化测试
  190. objectIndex += 1
  191. autotestBlock(objects)
  192. }
  193. }
  194. return
  195. }
  196. }
  197. // 异步第0号位置自动化测试
  198. autotestBlock(objects)
  199. }
  200. }
  201. @IBAction func relpaceAllAction(_ sender:NSButton) {
  202. // Replace all refrence images for all type
  203. self.startBtn.isEnabled = false
  204. self.replaceAllBtn.isEnabled = false
  205. DispatchQueue.global().async {
  206. // Update For Waiting
  207. for fileType in testFileTypes {
  208. let types = testTypeInfo[fileType] as! NSArray
  209. for typeInfo in types {
  210. let ti = typeInfo as! NSDictionary
  211. let type = ti["Type"] as! NSString
  212. let testObject = AutoTest.autoTestFor(fileType as NSString, type: type)
  213. testObject?.updateRefImage()
  214. }
  215. DispatchQueue.main.sync {
  216. self.reloadListData()
  217. }
  218. }
  219. DispatchQueue.main.async {
  220. self.startBtn.isEnabled = true
  221. self.advanceView.setAutoTestObj(self.advanceView._autoTestObj)
  222. }
  223. }
  224. }
  225. @IBAction func selectAllTestItem(_ sender:NSButton) {
  226. for fileType in testFileTypes {
  227. let types = testTypeInfo[fileType] as! NSArray
  228. for typeInfo in types {
  229. let ti = typeInfo as! NSDictionary
  230. let type = ti["Type"] as! NSString
  231. let testObject = AutoTest.autoTestFor(fileType as NSString, type: type)
  232. if nil != testObject {
  233. testObject?.setSelectedKeys((testObject?.keys())!)
  234. }
  235. }
  236. self.reloadListData()
  237. advanceView.setAutoTestObj(advanceView._autoTestObj)
  238. }
  239. }
  240. @IBAction func diselectAllTestItem(_ sender:NSButton) {
  241. for fileType in testFileTypes {
  242. let types = testTypeInfo[fileType] as! NSArray
  243. for typeInfo in types {
  244. let ti = typeInfo as! NSDictionary
  245. let type = ti["Type"] as! NSString
  246. let testObject = AutoTest.autoTestFor(fileType as NSString, type: type)
  247. if nil != testObject {
  248. testObject?.setSelectedKeys([])
  249. }
  250. }
  251. self.reloadListData()
  252. advanceView.setAutoTestObj(advanceView._autoTestObj)
  253. }
  254. }
  255. @IBAction func showCompareReportAction(_ sender:NSButton) {
  256. let files = NSMutableArray()
  257. for fileType in testFileTypes {
  258. let types = testTypeInfo[fileType] as! NSArray
  259. for typeInfo in types {
  260. let ti = typeInfo as! NSDictionary
  261. let type = ti["Type"] as! NSString
  262. let testObject = AutoTest.autoTestFor(fileType as NSString, type: type)
  263. let tFiles = testObject?.compareFiles();
  264. if (tFiles != nil && tFiles?.count != 0) {
  265. files.addObjects(from: tFiles as! [Any])
  266. }
  267. }
  268. }
  269. if files.count > 0 {
  270. let compareVC = CompareViewController.shared()
  271. compareVC.setFiles(files)
  272. let point = sender.convert(CGPoint(x: 0, y: 0), to: self.view.window?.contentView ?? self.view)
  273. compareVC.showIn(self.view.window?.contentView ?? self.view, rect: NSRect.init(origin: point, size: sender.frame.size))
  274. }
  275. return
  276. }
  277. // TableView Delegate
  278. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  279. let cellInfo = AutoTestCellInfo.initWithRow(row)
  280. if cellInfo.isFileType() {
  281. let cellView = TestFileTypeCellView.shared()
  282. let title = cellInfo.fileType()
  283. cellView?.setTitle(title)
  284. return cellView
  285. }else {
  286. let cellView = TestCaseCellView.shared()
  287. let autoTestObj = AutoTest.autoTestFor(NSString(string: (cellInfo.fileType())), type:NSString(string: (cellInfo.typeInfo()["Type"] as! String)))
  288. cellView?.setAutoTestObj(autoTestObj);
  289. cellView?.delegate = self;
  290. return cellView
  291. }
  292. }
  293. func selectionShouldChange(in tableView: NSTableView) -> Bool {
  294. return true
  295. }
  296. func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
  297. return true
  298. }
  299. func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
  300. return false
  301. }
  302. func tableView(_ tableView: NSTableView, mouseDownInHeaderOf tableColumn: NSTableColumn) {
  303. }
  304. func tableView(_ tableView: NSTableView, didClick tableColumn: NSTableColumn) {
  305. }
  306. func tableView(_ tableView: NSTableView, didDrag tableColumn: NSTableColumn) {
  307. }
  308. func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
  309. let cellInfo = AutoTestCellInfo.initWithRow(row)
  310. if cellInfo.isFileType() {
  311. return 30
  312. }else {
  313. return 60
  314. }
  315. }
  316. func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
  317. return false
  318. }
  319. func tableView(_ tableView: NSTableView, sizeToFitWidthOfColumn column: Int) -> CGFloat {
  320. return tableView.frame.width
  321. }
  322. func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
  323. return []
  324. }
  325. func tableViewSelectionDidChange(_ notification: Notification) {
  326. if ((notification.object as! NSTableView) == itemsList) {
  327. let selectRow = itemsList.selectedRow
  328. if selectRow != -1 {
  329. let cellInfo = AutoTestCellInfo.initWithRow(selectRow)
  330. if cellInfo.isFileType() {
  331. let isExpend = DataModel.shared.isExpand(cellInfo.fileType())
  332. DataModel.shared.setIsExpand(cellInfo.fileType(), expand: (!isExpend))
  333. itemsList.reloadData()
  334. }else {
  335. self.setCurrentCellInfo(cellInfo)
  336. }
  337. }else {
  338. }
  339. }
  340. }
  341. // TableView Data Source
  342. func numberOfRows(in tableView: NSTableView) -> Int {
  343. var count = testFileTypes.count
  344. for fileType in testFileTypes {
  345. //当前文件类型是否为展开
  346. if (DataModel.shared.isExpand(fileType)) {
  347. let testTypes = testTypeInfo[fileType] as! NSArray
  348. count = count + testTypes.count
  349. }
  350. }
  351. return count
  352. }
  353. /* This method is required for the "Cell Based" TableView, and is optional for the "View Based" TableView. If implemented in the latter case, the value will be set to the view at a given row/column if the view responds to -setObjectValue: (such as NSControl and NSTableCellView). Note that NSTableCellView does not actually display the objectValue, and its value is to be used for bindings. See NSTableCellView.h for more information.
  354. */
  355. // func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
  356. // return testCaseNames[row]
  357. // }
  358. // SettingViewConntroller Handle
  359. func settingViewDidFinished() {
  360. reloadListData()
  361. }
  362. //AutoTestAdvanceSettingView Delegate
  363. func advanceSettingDidUpdate(_ settingView: NSView?) {
  364. if (nil != _currentCellInfo) {
  365. itemsList.reloadData(forRowIndexes: IndexSet(integer: IndexSet.Element((_currentCellInfo?._row)!)),
  366. columnIndexes: IndexSet(integer: IndexSet.Element(0)))
  367. }else {
  368. reloadListData()
  369. }
  370. }
  371. //TestCaseCellViewDelegate
  372. func selectKeyDidUpdate(_ cell: NSTableCellView?) {
  373. advanceView._autoTestObj = advanceView._autoTestObj
  374. }
  375. }