ViewController.swift 17 KB

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