ViewController.swift 16 KB

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