├── .classpath ├── .gitattributes ├── .gitignore ├── .idea ├── .gitignore ├── .name ├── ant.xml ├── compiler.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jarRepositories.xml ├── misc.xml ├── uiDesigner.xml └── vcs.xml ├── .project ├── .settings ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs └── org.eclipse.m2e.core.prefs ├── LICENSE ├── Plug-in └── AutoIT │ ├── 上传软件使用许可证 │ ├── 172.19.5.33_audit.lic │ ├── 172.19.5.50_audit.lic │ ├── 上传软件使用许可证.au3 │ ├── 上传软件使用许可证.exe │ ├── 下载设备机器码.au3 │ └── 下载设备机器码.exe │ ├── 文件字符水印溯源 │ └── 文件字符水印溯源.xls │ ├── 文件脱敏到数据库 │ ├── 文件脱敏到数据库.au3 │ ├── 文件脱敏到数据库.exe │ └── 文件脱敏到数据库.xlsx │ └── 系统日志导出 │ ├── 系统日志.xlsx │ └── 系统日志导出.au3 ├── README.md ├── RunningLog └── ExtentReport.txt ├── TestData ├── Code │ ├── getCode.png │ ├── getCode.py │ └── getCode.txt ├── Excel │ └── TestData.xls ├── Key │ └── Keys.java └── Txt │ └── KeyCode.txt ├── TestOutput └── TestngReport │ ├── bullet_point.png │ ├── collapseall.gif │ ├── emailable-report.html │ ├── failed.png │ ├── index.html │ ├── jquery-1.7.1.min.js │ ├── navigator-bullet.png │ ├── old │ └── index.html │ ├── passed.png │ ├── skipped.png │ ├── testng-failed.xml │ ├── testng-reports.css │ ├── testng-reports.js │ ├── testng-results.xml │ └── testng.css ├── bin ├── BD │ └── V1_0_0 │ │ └── TestCases │ │ └── BD_SMOKE_001.class └── com │ └── sakura │ ├── base │ ├── StepAction.class │ ├── TestBase.class │ ├── TestCase.class │ ├── TestStep.class │ └── TestUnit.class │ ├── handler │ ├── AndroidSystemHandler.class │ ├── CheckActionHandler.class │ ├── ClearActionHandler.class │ ├── ClickActionHandler.class │ ├── DBActionHandler.class │ ├── ExecuteShellHandler.class │ ├── FileAction_Handler.class │ ├── FileReaderHandler.class │ ├── FreeSSH_FTP_Handler.class │ ├── GetCodeActionHandler.class │ ├── GetUrlActionHandler.class │ ├── HttpRequestHandler.class │ ├── InputActionHandler.class │ ├── RecordActionHandler.class │ ├── SetActionHandler.class │ ├── SlideActionHandler.class │ ├── WaitActionHandler$1.class │ ├── WaitActionHandler.class │ └── WindowsSystemHandler.class │ ├── service │ ├── AndroidXmlParseService.class │ ├── AppiumService.class │ ├── ExtentReportGenerateService$1.class │ ├── ExtentReportGenerateService.class │ ├── RunUnitService.class │ └── WebXmlParseService.class │ └── util │ ├── ANSIConsoleAppender.class │ ├── AppiumUtil.class │ ├── CommandUtil$ResultHandler.class │ ├── CommandUtil$SimpleResultHandler.class │ ├── CommandUtil.class │ ├── ConfigUtil.class │ ├── ConnDatabase.class │ ├── Constants.class │ ├── ConstantsUtil.class │ ├── CopyFile.class │ ├── DBHelper$MyUserInfo.class │ ├── DBHelper$OpType.class │ ├── DBHelper.class │ ├── DBSSH.class │ ├── DateUtil.class │ ├── ExcelHelper.class │ ├── ExcpUtil.class │ ├── ExecuteSSHToolUtil.class │ ├── ExecuteShellUtil.class │ ├── FileReaderUtil$1.class │ ├── FileReaderUtil.class │ ├── FileUtil$1.class │ ├── FileUtil.class │ ├── FreeSFTPUtil.class │ ├── FreeSSHUtil.class │ ├── GetInfo.class │ ├── HttpGetRequestUtil.class │ ├── HttpPostRequestUtil.class │ ├── HttpRequestUtil.class │ ├── ImageUtil$1.class │ ├── ImageUtil.class │ ├── JSchUtil.class │ ├── JsonUtil$1.class │ ├── JsonUtil$2.class │ ├── JsonUtil$3.class │ ├── JsonUtil$4.class │ ├── JsonUtil.class │ ├── Log4jUtil$BeginFileData.class │ ├── Log4jUtil.class │ ├── MapUtil.class │ ├── MongoDBUtil$OperationType.class │ ├── MongoDBUtil.class │ ├── MongoDBUtil1.class │ ├── MouseUtil.class │ ├── ObsRemoteUtil$1.class │ ├── ObsRemoteUtil$ObsWebSocketEndpoint.class │ ├── ObsRemoteUtil.class │ ├── OrderedProperties.class │ ├── PingUtil.class │ ├── RegexUtil.class │ ├── ScreenCaptureExample.class │ ├── ScreenRecorderTest.class │ ├── ScreenRecorderUtil.class │ ├── SeleniumUtil$1.class │ ├── SeleniumUtil.class │ ├── StringUtil.class │ ├── SystemOutUtil.class │ ├── SystemUtil.class │ ├── VideoRecorder$1.class │ ├── VideoRecorder$2.class │ ├── VideoRecorder.class │ ├── ZipUtil.class │ └── maintest.class ├── build.xml ├── lib ├── DataBase │ ├── cache-jdbc.jar │ ├── gbase8a-jdbc.jar │ ├── gbase8s-jdbc.jar │ ├── hive-jdbc-3.1.3.jar │ ├── hive-jdbc-uber-2.6.5.0-292.jar │ ├── ojdbc7-12.1.0.2.jar │ └── sybase-jdbc-jconn4.jar ├── Excel │ └── jxl.jar ├── Json │ └── json-2.0.jar ├── Log4j │ ├── log4j-1.2.16.jar │ ├── slf4j-api-1.6.6.jar │ └── slf4j-log4j12-1.6.6.jar ├── Selenium │ └── selenium-server-standalone-2.53.0.jar ├── Tentng │ └── testng-6.9.10.jar └── TestReport │ ├── ExtentReport │ ├── extentreports-2.41.2.jar │ ├── extentreports-3.0.6.jar │ ├── extentreports-java-2.41.1.jar │ ├── freemarker-2.3.23.jar │ ├── guice-3.0.jar │ └── mongo-java-driver-3.3.0.jar │ └── TestngReport │ ├── reportng-1.1.5.jar │ ├── saxon-8.7.jar │ ├── testng-results.xsl │ └── velocity-1.7-dep.jar ├── pom.xml ├── run.sh └── src ├── main ├── java │ ├── com │ │ └── sakura │ │ │ ├── base │ │ │ ├── StepAction.java │ │ │ ├── TestBase.java │ │ │ ├── TestCase.java │ │ │ ├── TestStep.java │ │ │ └── TestUnit.java │ │ │ ├── handler │ │ │ ├── AndroidSystemHandler.java │ │ │ ├── CheckActionHandler.java │ │ │ ├── ClearActionHandler.java │ │ │ ├── ClickActionHandler.java │ │ │ ├── DBActionHandler.java │ │ │ ├── ExecuteShellHandler.java │ │ │ ├── FileAction_Handler.java │ │ │ ├── FileReaderHandler.java │ │ │ ├── FreeSSH_FTP_Handler.java │ │ │ ├── GetCodeActionHandler.java │ │ │ ├── GetUrlActionHandler.java │ │ │ ├── HttpRequestHandler.java │ │ │ ├── InputActionHandler.java │ │ │ ├── RecordActionHandler.java │ │ │ ├── SetActionHandler.java │ │ │ ├── SlideActionHandler.java │ │ │ ├── WaitActionHandler.java │ │ │ └── WindowsSystemHandler.java │ │ │ ├── service │ │ │ ├── AndroidXmlParseService.java │ │ │ ├── AppiumService.java │ │ │ ├── ExtentReportGenerateService.java │ │ │ ├── ExtentReportGenerateService2.java │ │ │ ├── RunUnitService.java │ │ │ └── WebXmlParseService.java │ │ │ └── util │ │ │ ├── ANSIConsoleAppender.java │ │ │ ├── AppiumUtil.java │ │ │ ├── CommandUtil.java │ │ │ ├── ConfigUtil.java │ │ │ ├── ConnDatabase.java │ │ │ ├── Constants.java │ │ │ ├── ConstantsUtil.java │ │ │ ├── CopyFile.java │ │ │ ├── DBHelper.java │ │ │ ├── DBSSH.java │ │ │ ├── DateUtil.java │ │ │ ├── ExcelHelper.java │ │ │ ├── ExcpUtil.java │ │ │ ├── ExecuteSSHToolUtil.java │ │ │ ├── ExecuteShellUtil.java │ │ │ ├── FileReaderUtil.java │ │ │ ├── FileUtil.java │ │ │ ├── FreeSFTPUtil.java │ │ │ ├── FreeSSHUtil.java │ │ │ ├── GetInfo.java │ │ │ ├── HttpGetRequestUtil.java │ │ │ ├── HttpPostRequestUtil.java │ │ │ ├── HttpRequestUtil.java │ │ │ ├── ImageUtil.java │ │ │ ├── JSchUtil.java │ │ │ ├── JsonUtil.java │ │ │ ├── Log4jUtil.java │ │ │ ├── MapUtil.java │ │ │ ├── MongoDBUtil.java │ │ │ ├── MongoDBUtil1.java │ │ │ ├── MouseUtil.java │ │ │ ├── ObsRemoteUtil.java │ │ │ ├── OrderedProperties.java │ │ │ ├── PingUtil.java │ │ │ ├── RegexUtil.java │ │ │ ├── ScreenCaptureExample.java │ │ │ ├── ScreenRecorderTest.java │ │ │ ├── ScreenRecorderUtil.java │ │ │ ├── SeleniumUtil.java │ │ │ ├── StringUtil.java │ │ │ ├── SystemOutUtil.java │ │ │ ├── SystemUtil.java │ │ │ ├── VideoRecorder.java │ │ │ ├── ZipUtil.java │ │ │ └── maintest.java │ ├── common.properties │ ├── jdbc.properties │ ├── log4j.properties │ └── lombok.config └── resources │ ├── chromedriver.exe │ ├── geckodriver.exe │ └── id_rsa └── test └── java ├── BD └── V1_0_0 │ ├── TestCaseXml │ └── BD_SMOKE_001.xml │ ├── TestCases │ └── BD_SMOKE_001.java │ └── TestReportXml │ └── 172.18.1.118.xml └── TestRunXml └── ExtentReport.xml /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | #lib/DataBase/phoenix-client-hbase-1.3-4.16.1.jar filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /Logs/ 3 | /TestOutput/ 4 | /test-output/ 5 | /lib/DataBase/phoenix-client-hbase-1.3-4.16.1.jar -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | sakura-selenium -------------------------------------------------------------------------------- /.idea/ant.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | sakura-selenium 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/java/common.properties=UTF-8 4 | encoding//src/main/java/jdbc.properties=UTF-8 5 | encoding//src/main/java/log4j.properties=UTF-8 6 | encoding//src/test/java=UTF-8 7 | encoding//src/test/resources=UTF-8 8 | encoding/=UTF-8 9 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.8 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore 14 | org.eclipse.jdt.core.compiler.release=disabled 15 | org.eclipse.jdt.core.compiler.source=1.8 16 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /Plug-in/AutoIT/上传软件使用许可证/172.19.5.33_audit.lic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/上传软件使用许可证/172.19.5.33_audit.lic -------------------------------------------------------------------------------- /Plug-in/AutoIT/上传软件使用许可证/172.19.5.50_audit.lic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/上传软件使用许可证/172.19.5.50_audit.lic -------------------------------------------------------------------------------- /Plug-in/AutoIT/上传软件使用许可证/上传软件使用许可证.au3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/上传软件使用许可证/上传软件使用许可证.au3 -------------------------------------------------------------------------------- /Plug-in/AutoIT/上传软件使用许可证/上传软件使用许可证.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/上传软件使用许可证/上传软件使用许可证.exe -------------------------------------------------------------------------------- /Plug-in/AutoIT/上传软件使用许可证/下载设备机器码.au3: -------------------------------------------------------------------------------- 1 | ;ControlFocus("title","text",controlID) Edit1=Edit instance 1 2 | ;control ID由class和instance组成 3 | ;识别windows窗口 4 | ControlFocus("另存为", "","Edit1") 5 | 6 | ; Wait 10 seconds for the Upload window to appear 7 | ;窗口等待十秒 8 | WinWait("[CLASS:#32770]","",10) 9 | 10 | 11 | ; Set the File name text on the Edit field 12 | ;想输入框中输入需要上传的地址 13 | ControlSetText("另存为", "", "Edit1", "D:\Jenkins\workspace\Sakura.Web.UI.Automation.Test\Plug-in\AutoIT\下载设备机器码\172.19.3.15.info") 14 | 15 | Sleep(1000) 16 | 17 | ; Click on the Open button 18 | ;点击[另存为】按钮 19 | ControlClick("另存为", "","Button2"); -------------------------------------------------------------------------------- /Plug-in/AutoIT/上传软件使用许可证/下载设备机器码.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/上传软件使用许可证/下载设备机器码.exe -------------------------------------------------------------------------------- /Plug-in/AutoIT/文件字符水印溯源/文件字符水印溯源.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/文件字符水印溯源/文件字符水印溯源.xls -------------------------------------------------------------------------------- /Plug-in/AutoIT/文件脱敏到数据库/文件脱敏到数据库.au3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/文件脱敏到数据库/文件脱敏到数据库.au3 -------------------------------------------------------------------------------- /Plug-in/AutoIT/文件脱敏到数据库/文件脱敏到数据库.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/文件脱敏到数据库/文件脱敏到数据库.exe -------------------------------------------------------------------------------- /Plug-in/AutoIT/文件脱敏到数据库/文件脱敏到数据库.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/文件脱敏到数据库/文件脱敏到数据库.xlsx -------------------------------------------------------------------------------- /Plug-in/AutoIT/系统日志导出/系统日志.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/系统日志导出/系统日志.xlsx -------------------------------------------------------------------------------- /Plug-in/AutoIT/系统日志导出/系统日志导出.au3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/Plug-in/AutoIT/系统日志导出/系统日志导出.au3 -------------------------------------------------------------------------------- /RunningLog/ExtentReport.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/RunningLog/ExtentReport.txt -------------------------------------------------------------------------------- /TestData/Code/getCode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestData/Code/getCode.png -------------------------------------------------------------------------------- /TestData/Code/getCode.py: -------------------------------------------------------------------------------- 1 | import ddddocr 2 | import time 3 | import sys 4 | 5 | begin=time.time() 6 | ocr = ddddocr.DdddOcr() 7 | 8 | def func(file,name): 9 | with open(file,'rb') as f: 10 | 11 | img_bytes = f.read() 12 | 13 | res = ocr.classification(img_bytes) 14 | 15 | file = open(name, mode='w') 16 | file.write(res) 17 | 18 | finish=time.time() 19 | print("结果:") 20 | print("用时:%s 秒" % str(finish-begin)) 21 | print(res+"=") 22 | return res 23 | 24 | if __name__ == '__main__': 25 | func(sys.argv[1],sys.argv[2]) 26 | # func('D:\Jenkins\workspace\Sakura.Web.UI.Automation.Test\TestData\Code\getCode.png','D:\Jenkins\workspace\Sakura.Web.UI.Automation.Test\TestData\Code\getCode.txt') 27 | -------------------------------------------------------------------------------- /TestData/Code/getCode.txt: -------------------------------------------------------------------------------- 1 | hdac -------------------------------------------------------------------------------- /TestData/Excel/TestData.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestData/Excel/TestData.xls -------------------------------------------------------------------------------- /TestData/Key/Keys.java: -------------------------------------------------------------------------------- 1 | // Licensed to the Software Freedom Conservancy (SFC) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The SFC licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package org.openqa.selenium; 19 | 20 | import java.util.Arrays; 21 | 22 | /** 23 | * Representations of pressable keys that aren't text. These are stored in the Unicode PUA (Private 24 | * Use Area) code points, 0xE000-0xF8FF. 25 | * 26 | * @see http://www.google.com.au/search?&q=unicode+pua&btnK=Search 27 | */ 28 | public enum Keys implements CharSequence { 29 | 30 | NULL ('\uE000'), 31 | CANCEL ('\uE001'), // ^break 32 | HELP ('\uE002'), 33 | BACK_SPACE ('\uE003'), 34 | TAB ('\uE004'), 35 | CLEAR ('\uE005'), 36 | RETURN ('\uE006'), 37 | ENTER ('\uE007'), 38 | SHIFT ('\uE008'), 39 | LEFT_SHIFT (Keys.SHIFT), 40 | CONTROL ('\uE009'), 41 | LEFT_CONTROL (Keys.CONTROL), 42 | ALT ('\uE00A'), 43 | LEFT_ALT (Keys.ALT), 44 | PAUSE ('\uE00B'), 45 | ESCAPE ('\uE00C'), 46 | SPACE ('\uE00D'), 47 | PAGE_UP ('\uE00E'), 48 | PAGE_DOWN ('\uE00F'), 49 | END ('\uE010'), 50 | HOME ('\uE011'), 51 | LEFT ('\uE012'), 52 | ARROW_LEFT (Keys.LEFT), 53 | UP ('\uE013'), 54 | ARROW_UP (Keys.UP), 55 | RIGHT ('\uE014'), 56 | ARROW_RIGHT (Keys.RIGHT), 57 | DOWN ('\uE015'), 58 | ARROW_DOWN (Keys.DOWN), 59 | INSERT ('\uE016'), 60 | DELETE ('\uE017'), 61 | SEMICOLON ('\uE018'), 62 | EQUALS ('\uE019'), 63 | 64 | // Number pad keys 65 | NUMPAD0 ('\uE01A'), 66 | NUMPAD1 ('\uE01B'), 67 | NUMPAD2 ('\uE01C'), 68 | NUMPAD3 ('\uE01D'), 69 | NUMPAD4 ('\uE01E'), 70 | NUMPAD5 ('\uE01F'), 71 | NUMPAD6 ('\uE020'), 72 | NUMPAD7 ('\uE021'), 73 | NUMPAD8 ('\uE022'), 74 | NUMPAD9 ('\uE023'), 75 | MULTIPLY ('\uE024'), 76 | ADD ('\uE025'), 77 | SEPARATOR ('\uE026'), 78 | SUBTRACT ('\uE027'), 79 | DECIMAL ('\uE028'), 80 | DIVIDE ('\uE029'), 81 | 82 | // Function keys 83 | F1 ('\uE031'), 84 | F2 ('\uE032'), 85 | F3 ('\uE033'), 86 | F4 ('\uE034'), 87 | F5 ('\uE035'), 88 | F6 ('\uE036'), 89 | F7 ('\uE037'), 90 | F8 ('\uE038'), 91 | F9 ('\uE039'), 92 | F10 ('\uE03A'), 93 | F11 ('\uE03B'), 94 | F12 ('\uE03C'), 95 | 96 | META ('\uE03D'), 97 | COMMAND (Keys.META), 98 | 99 | ZENKAKU_HANKAKU ('\uE040'); 100 | 101 | private final char keyCode; 102 | private final int codePoint; 103 | 104 | Keys(Keys key) { 105 | this(key.charAt(0)); 106 | } 107 | 108 | Keys(char keyCode) { 109 | this.keyCode = keyCode; 110 | this.codePoint = String.valueOf(keyCode).codePoints().findFirst().getAsInt(); 111 | } 112 | 113 | public int getCodePoint() { 114 | return codePoint; 115 | } 116 | 117 | public char charAt(int index) { 118 | if (index == 0) { 119 | return keyCode; 120 | } 121 | 122 | return 0; 123 | } 124 | 125 | public int length() { 126 | return 1; 127 | } 128 | 129 | public CharSequence subSequence(int start, int end) { 130 | if (start == 0 && end == 1) { 131 | return String.valueOf(keyCode); 132 | } 133 | 134 | throw new IndexOutOfBoundsException(); 135 | } 136 | 137 | @Override 138 | public String toString() { 139 | return String.valueOf(keyCode); 140 | } 141 | 142 | /** 143 | * Simulate pressing many keys at once in a "chord". Takes a sequence of Keys.XXXX or strings; 144 | * appends each of the values to a string, and adds the chord termination key (Keys.NULL) and 145 | * returns the resultant string. 146 | * 147 | * Note: When the low-level webdriver key handlers see Keys.NULL, active modifier keys 148 | * (CTRL/ALT/SHIFT/etc) release via a keyup event. 149 | * 150 | * Issue: http://code.google.com/p/webdriver/issues/detail?id=79 151 | * 152 | * @param value characters to send 153 | * @return String representation of the char sequence 154 | */ 155 | public static String chord(CharSequence... value) { 156 | return chord(Arrays.asList(value)); 157 | } 158 | 159 | /** 160 | * @see #chord(CharSequence...) 161 | * @param value characters to send 162 | * @return String representation of the char sequence 163 | */ 164 | public static String chord(Iterable value) { 165 | StringBuilder builder = new StringBuilder(); 166 | 167 | for (CharSequence seq : value) { 168 | builder.append(seq); 169 | } 170 | 171 | builder.append(Keys.NULL); 172 | return builder.toString(); 173 | } 174 | 175 | /** 176 | * Get the special key representation, {@link Keys}, of the supplied character if there is one. If 177 | * there is no special key tied to this character, null will be returned. 178 | * 179 | * @param key unicode character code 180 | * @return special key linked to the character code, or null if character is not a special key 181 | */ 182 | public static Keys getKeyFromUnicode(char key) { 183 | for (Keys unicodeKey : values()) { 184 | if (unicodeKey.charAt(0) == key) { 185 | return unicodeKey; 186 | } 187 | } 188 | 189 | return null; 190 | } 191 | } -------------------------------------------------------------------------------- /TestData/Txt/KeyCode.txt: -------------------------------------------------------------------------------- 1 | 2 | 附录 KeyCode 3 | 4 | 电话键 5 | KEYCODE_CALL 拨号键 5 6 | KEYCODE_ENDCALL 挂机键 6 7 | KEYCODE_HOME 按键Home 3 8 | KEYCODE_MENU 菜单键 82 9 | KEYCODE_BACK 返回键 4 10 | KEYCODE_SEARCH 搜索键 84 11 | KEYCODE_CAMERA 拍照键 27 12 | KEYCODE_FOCUS 拍照对焦键 80 13 | KEYCODE_POWER 电源键 26 14 | KEYCODE_NOTIFICATION 通知键 83 15 | KEYCODE_MUTE 话筒静音键 91 16 | KEYCODE_VOLUME_MUTE 扬声器静音键 164 17 | KEYCODE_VOLUME_UP 音量增加键 24 18 | KEYCODE_VOLUME_DOWN 音量减小键 25 19 | 20 | 控制键 21 | KEYCODE_ENTER 回车键 66 22 | KEYCODE_ESCAPE ESC键 111 23 | KEYCODE_DPAD_CENTER 导航键 确定键 23 24 | KEYCODE_DPAD_UP 导航键 向上 19 25 | KEYCODE_DPAD_DOWN 导航键 向下 20 26 | KEYCODE_DPAD_LEFT 导航键 向左 21 27 | KEYCODE_DPAD_RIGHT 导航键 向右 22 28 | KEYCODE_MOVE_HOME 光标移动到开始键 122 29 | KEYCODE_MOVE_END 光标移动到末尾键 123 30 | KEYCODE_PAGE_UP 向上翻页键 92 31 | KEYCODE_PAGE_DOWN 向下翻页键 93 32 | KEYCODE_DEL 退格键 67 33 | KEYCODE_FORWARD_DEL 删除键 112 34 | KEYCODE_INSERT 插入键 124 35 | KEYCODE_TAB Tab键 61 36 | KEYCODE_NUM_LOCK 小键盘锁 143 37 | KEYCODE_CAPS_LOCK 大写锁定键 115 38 | KEYCODE_BREAK Break/Pause键 121 39 | KEYCODE_SCROLL_LOCK 滚动锁定键 116 40 | KEYCODE_ZOOM_IN 放大键 168 41 | KEYCODE_ZOOM_OUT 缩小键 169 42 | 43 | 组合键 44 | KEYCODE_ALT_LEFT Alt+Left 45 | KEYCODE_ALT_RIGHT Alt+Right 46 | KEYCODE_CTRL_LEFT Control+Left 47 | KEYCODE_CTRL_RIGHT Control+Right 48 | KEYCODE_SHIFT_LEFT Shift+Left 49 | KEYCODE_SHIFT_RIGHT Shift+Right 50 | 51 | 基本 52 | KEYCODE_0 按键'0' 7 53 | KEYCODE_1 按键'1' 8 54 | KEYCODE_2 按键'2' 9 55 | KEYCODE_3 按键'3' 10 56 | KEYCODE_4 按键'4' 11 57 | KEYCODE_5 按键'5' 12 58 | KEYCODE_6 按键'6' 13 59 | KEYCODE_7 按键'7' 14 60 | KEYCODE_8 按键'8' 15 61 | KEYCODE_9 按键'9' 16 62 | KEYCODE_A 按键'A' 29 63 | KEYCODE_B 按键'B' 30 64 | KEYCODE_C 按键'C' 31 65 | KEYCODE_D 按键'D' 32 66 | KEYCODE_E 按键'E' 33 67 | KEYCODE_F 按键'F' 34 68 | KEYCODE_G 按键'G' 35 69 | KEYCODE_H 按键'H' 36 70 | KEYCODE_I 按键'I' 37 71 | KEYCODE_J 按键'J' 38 72 | KEYCODE_K 按键'K' 39 73 | KEYCODE_L 按键'L' 40 74 | KEYCODE_M 按键'M' 41 75 | KEYCODE_N 按键'N' 42 76 | KEYCODE_O 按键'O' 43 77 | KEYCODE_P 按键'P' 44 78 | KEYCODE_Q 按键'Q' 45 79 | KEYCODE_R 按键'R' 46 80 | KEYCODE_S 按键'S' 47 81 | KEYCODE_T 按键'T' 48 82 | KEYCODE_U 按键'U' 49 83 | KEYCODE_V 按键'V' 50 84 | KEYCODE_W 按键'W' 51 85 | KEYCODE_X 按键'X' 52 86 | KEYCODE_Y 按键'Y' 53 87 | KEYCODE_Z 按键'Z' 54 -------------------------------------------------------------------------------- /TestOutput/TestngReport/bullet_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestOutput/TestngReport/bullet_point.png -------------------------------------------------------------------------------- /TestOutput/TestngReport/collapseall.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestOutput/TestngReport/collapseall.gif -------------------------------------------------------------------------------- /TestOutput/TestngReport/emailable-report.html: -------------------------------------------------------------------------------- 1 | 2 | TestNG Report
Test# Passed# Skipped# FailedTime (ms)Included GroupsExcluded Groups
Suite
百度系统
百度搜索场景测试20085,737
ClassMethodStartTime (ms)
Suite
百度系统
百度搜索场景测试 — passed
BD.V1_0_0.TestCases.BD_SMOKE_001BD_00117432340093663282
BD_00217432340126491518

百度搜索场景测试

BD.V1_0_0.TestCases.BD_SMOKE_001#BD_001

Messages
验证打开百度搜索域名,可以正常访问,并进入百度搜索页面

back to summary

BD.V1_0_0.TestCases.BD_SMOKE_001#BD_002

Messages
验证在百度搜索页面,输入关键字,点击百度一下按钮,可以正常搜索,并进入搜索结果页面

back to summary

-------------------------------------------------------------------------------- /TestOutput/TestngReport/failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestOutput/TestngReport/failed.png -------------------------------------------------------------------------------- /TestOutput/TestngReport/navigator-bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestOutput/TestngReport/navigator-bullet.png -------------------------------------------------------------------------------- /TestOutput/TestngReport/old/index.html: -------------------------------------------------------------------------------- 1 | 2 | Test results 3 | 4 | 5 |

Test results

6 | 7 | 8 | 9 |
SuitePassedFailedSkippedtestng.xml
Total200 
百度系统200Link
10 | -------------------------------------------------------------------------------- /TestOutput/TestngReport/passed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestOutput/TestngReport/passed.png -------------------------------------------------------------------------------- /TestOutput/TestngReport/skipped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/TestOutput/TestngReport/skipped.png -------------------------------------------------------------------------------- /TestOutput/TestngReport/testng-failed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /TestOutput/TestngReport/testng-reports.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0px 0px 5px 5px; 3 | } 4 | 5 | ul { 6 | margin: 0px; 7 | } 8 | 9 | li { 10 | list-style-type: none; 11 | } 12 | 13 | a { 14 | text-decoration: none; 15 | } 16 | 17 | a:hover { 18 | text-decoration: underline; 19 | } 20 | 21 | .navigator-selected { 22 | background: #ffa500; 23 | } 24 | 25 | .wrapper { 26 | position: absolute; 27 | top: 60px; 28 | bottom: 0; 29 | left: 400px; 30 | right: 0; 31 | overflow: auto; 32 | } 33 | 34 | .navigator-root { 35 | position: absolute; 36 | top: 60px; 37 | bottom: 0; 38 | left: 0; 39 | width: 400px; 40 | overflow-y: auto; 41 | } 42 | 43 | .suite { 44 | margin: 0px 10px 10px 0px; 45 | background-color: #fff8dc; 46 | } 47 | 48 | .suite-name { 49 | padding-left: 10px; 50 | font-size: 25px; 51 | font-family: Times; 52 | } 53 | 54 | .main-panel-header { 55 | padding: 5px; 56 | background-color: #9FB4D9; //afeeee; 57 | font-family: monospace; 58 | font-size: 18px; 59 | } 60 | 61 | .main-panel-content { 62 | padding: 5px; 63 | margin-bottom: 10px; 64 | background-color: #DEE8FC; //d0ffff; 65 | } 66 | 67 | .rounded-window { 68 | border-radius: 10px; 69 | border-style: solid; 70 | border-width: 1px; 71 | } 72 | 73 | .rounded-window-top { 74 | border-top-right-radius: 10px 10px; 75 | border-top-left-radius: 10px 10px; 76 | border-style: solid; 77 | border-width: 1px; 78 | overflow: auto; 79 | } 80 | 81 | .light-rounded-window-top { 82 | border-top-right-radius: 10px 10px; 83 | border-top-left-radius: 10px 10px; 84 | } 85 | 86 | .rounded-window-bottom { 87 | border-style: solid; 88 | border-width: 0px 1px 1px 1px; 89 | border-bottom-right-radius: 10px 10px; 90 | border-bottom-left-radius: 10px 10px; 91 | overflow: auto; 92 | } 93 | 94 | .method-name { 95 | font-size: 12px; 96 | font-family: monospace; 97 | } 98 | 99 | .method-content { 100 | border-style: solid; 101 | border-width: 0px 0px 1px 0px; 102 | margin-bottom: 10; 103 | padding-bottom: 5px; 104 | width: 80%; 105 | } 106 | 107 | .parameters { 108 | font-size: 14px; 109 | font-family: monospace; 110 | } 111 | 112 | .stack-trace { 113 | white-space: pre; 114 | font-family: monospace; 115 | font-size: 12px; 116 | font-weight: bold; 117 | margin-top: 0px; 118 | margin-left: 20px; 119 | } 120 | 121 | .testng-xml { 122 | font-family: monospace; 123 | } 124 | 125 | .method-list-content { 126 | margin-left: 10px; 127 | } 128 | 129 | .navigator-suite-content { 130 | margin-left: 10px; 131 | font: 12px 'Lucida Grande'; 132 | } 133 | 134 | .suite-section-title { 135 | margin-top: 10px; 136 | width: 80%; 137 | border-style: solid; 138 | border-width: 1px 0px 0px 0px; 139 | font-family: Times; 140 | font-size: 18px; 141 | font-weight: bold; 142 | } 143 | 144 | .suite-section-content { 145 | list-style-image: url(bullet_point.png); 146 | } 147 | 148 | .top-banner-root { 149 | position: absolute; 150 | top: 0; 151 | height: 45px; 152 | left: 0; 153 | right: 0; 154 | padding: 5px; 155 | margin: 0px 0px 5px 0px; 156 | background-color: #0066ff; 157 | font-family: Times; 158 | color: #fff; 159 | text-align: center; 160 | } 161 | 162 | .top-banner-title-font { 163 | font-size: 25px; 164 | } 165 | 166 | .test-name { 167 | font-family: 'Lucida Grande'; 168 | font-size: 16px; 169 | } 170 | 171 | .suite-icon { 172 | padding: 5px; 173 | float: right; 174 | height: 20; 175 | } 176 | 177 | .test-group { 178 | font: 20px 'Lucida Grande'; 179 | margin: 5px 5px 10px 5px; 180 | border-width: 0px 0px 1px 0px; 181 | border-style: solid; 182 | padding: 5px; 183 | } 184 | 185 | .test-group-name { 186 | font-weight: bold; 187 | } 188 | 189 | .method-in-group { 190 | font-size: 16px; 191 | margin-left: 80px; 192 | } 193 | 194 | table.google-visualization-table-table { 195 | width: 100%; 196 | } 197 | 198 | .reporter-method-name { 199 | font-size: 14px; 200 | font-family: monospace; 201 | } 202 | 203 | .reporter-method-output-div { 204 | padding: 5px; 205 | margin: 0px 0px 5px 20px; 206 | font-size: 12px; 207 | font-family: monospace; 208 | border-width: 0px 0px 0px 1px; 209 | border-style: solid; 210 | } 211 | 212 | .ignored-class-div { 213 | font-size: 14px; 214 | font-family: monospace; 215 | } 216 | 217 | .ignored-methods-div { 218 | padding: 5px; 219 | margin: 0px 0px 5px 20px; 220 | font-size: 12px; 221 | font-family: monospace; 222 | border-width: 0px 0px 0px 1px; 223 | border-style: solid; 224 | } 225 | 226 | .border-failed { 227 | border-top-left-radius: 10px 10px; 228 | border-bottom-left-radius: 10px 10px; 229 | border-style: solid; 230 | border-width: 0px 0px 0px 10px; 231 | border-color: #f00; 232 | } 233 | 234 | .border-skipped { 235 | border-top-left-radius: 10px 10px; 236 | border-bottom-left-radius: 10px 10px; 237 | border-style: solid; 238 | border-width: 0px 0px 0px 10px; 239 | border-color: #edc600; 240 | } 241 | 242 | .border-passed { 243 | border-top-left-radius: 10px 10px; 244 | border-bottom-left-radius: 10px 10px; 245 | border-style: solid; 246 | border-width: 0px 0px 0px 10px; 247 | border-color: #19f52d; 248 | } 249 | 250 | .times-div { 251 | text-align: center; 252 | padding: 5px; 253 | } 254 | 255 | .suite-total-time { 256 | font: 16px 'Lucida Grande'; 257 | } 258 | 259 | .configuration-suite { 260 | margin-left: 20px; 261 | } 262 | 263 | .configuration-test { 264 | margin-left: 40px; 265 | } 266 | 267 | .configuration-class { 268 | margin-left: 60px; 269 | } 270 | 271 | .configuration-method { 272 | margin-left: 80px; 273 | } 274 | 275 | .test-method { 276 | margin-left: 100px; 277 | } 278 | 279 | .chronological-class { 280 | background-color: #0ccff; 281 | border-style: solid; 282 | border-width: 0px 0px 1px 1px; 283 | } 284 | 285 | .method-start { 286 | float: right; 287 | } 288 | 289 | .chronological-class-name { 290 | padding: 0px 0px 0px 5px; 291 | color: #008; 292 | } 293 | 294 | .after, .before, .test-method { 295 | font-family: monospace; 296 | font-size: 14px; 297 | } 298 | 299 | .navigator-suite-header { 300 | font-size: 22px; 301 | margin: 0px 10px 5px 0px; 302 | background-color: #deb887; 303 | text-align: center; 304 | } 305 | 306 | .collapse-all-icon { 307 | padding: 5px; 308 | float: right; 309 | } 310 | -------------------------------------------------------------------------------- /TestOutput/TestngReport/testng-reports.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('a.navigator-link').click(function() { 3 | // Extract the panel for this link 4 | var panel = getPanelName($(this)); 5 | 6 | // Mark this link as currently selected 7 | $('.navigator-link').parent().removeClass('navigator-selected'); 8 | $(this).parent().addClass('navigator-selected'); 9 | 10 | showPanel(panel); 11 | }); 12 | 13 | installMethodHandlers('failed'); 14 | installMethodHandlers('skipped'); 15 | installMethodHandlers('passed', true); // hide passed methods by default 16 | 17 | $('a.method').click(function() { 18 | showMethod($(this)); 19 | return false; 20 | }); 21 | 22 | // Hide all the panels and display the first one (do this last 23 | // to make sure the click() will invoke the listeners) 24 | $('.panel').hide(); 25 | $('.navigator-link').first().click(); 26 | 27 | // Collapse/expand the suites 28 | $('a.collapse-all-link').click(function() { 29 | var contents = $('.navigator-suite-content'); 30 | if (contents.css('display') == 'none') { 31 | contents.show(); 32 | } else { 33 | contents.hide(); 34 | } 35 | }); 36 | }); 37 | 38 | // The handlers that take care of showing/hiding the methods 39 | function installMethodHandlers(name, hide) { 40 | function getContent(t) { 41 | return $('.method-list-content.' + name + "." + t.attr('panel-name')); 42 | } 43 | 44 | function getHideLink(t, name) { 45 | var s = 'a.hide-methods.' + name + "." + t.attr('panel-name'); 46 | return $(s); 47 | } 48 | 49 | function getShowLink(t, name) { 50 | return $('a.show-methods.' + name + "." + t.attr('panel-name')); 51 | } 52 | 53 | function getMethodPanelClassSel(element, name) { 54 | var panelName = getPanelName(element); 55 | var sel = '.' + panelName + "-class-" + name; 56 | return $(sel); 57 | } 58 | 59 | $('a.hide-methods.' + name).click(function() { 60 | var w = getContent($(this)); 61 | w.hide(); 62 | getHideLink($(this), name).hide(); 63 | getShowLink($(this), name).show(); 64 | getMethodPanelClassSel($(this), name).hide(); 65 | }); 66 | 67 | $('a.show-methods.' + name).click(function() { 68 | var w = getContent($(this)); 69 | w.show(); 70 | getHideLink($(this), name).show(); 71 | getShowLink($(this), name).hide(); 72 | showPanel(getPanelName($(this))); 73 | getMethodPanelClassSel($(this), name).show(); 74 | }); 75 | 76 | if (hide) { 77 | $('a.hide-methods.' + name).click(); 78 | } else { 79 | $('a.show-methods.' + name).click(); 80 | } 81 | } 82 | 83 | function getHashForMethod(element) { 84 | return element.attr('hash-for-method'); 85 | } 86 | 87 | function getPanelName(element) { 88 | return element.attr('panel-name'); 89 | } 90 | 91 | function showPanel(panelName) { 92 | $('.panel').hide(); 93 | var panel = $('.panel[panel-name="' + panelName + '"]'); 94 | panel.show(); 95 | } 96 | 97 | function showMethod(element) { 98 | var hashTag = getHashForMethod(element); 99 | var panelName = getPanelName(element); 100 | showPanel(panelName); 101 | var current = document.location.href; 102 | var base = current.substring(0, current.indexOf('#')) 103 | document.location.href = base + '#' + hashTag; 104 | var newPosition = $(document).scrollTop() - 65; 105 | $(document).scrollTop(newPosition); 106 | } 107 | 108 | function drawTable() { 109 | for (var i = 0; i < suiteTableInitFunctions.length; i++) { 110 | window[suiteTableInitFunctions[i]](); 111 | } 112 | 113 | for (var k in window.suiteTableData) { 114 | var v = window.suiteTableData[k]; 115 | var div = v.tableDiv; 116 | var data = v.tableData 117 | var table = new google.visualization.Table(document.getElementById(div)); 118 | table.draw(data, { 119 | showRowNumber : false 120 | }); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /TestOutput/TestngReport/testng-results.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /TestOutput/TestngReport/testng.css: -------------------------------------------------------------------------------- 1 | .invocation-failed, .test-failed { background-color: #DD0000; } 2 | .invocation-percent, .test-percent { background-color: #006600; } 3 | .invocation-passed, .test-passed { background-color: #00AA00; } 4 | .invocation-skipped, .test-skipped { background-color: #CCCC00; } 5 | 6 | .main-page { 7 | font-size: x-large; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /bin/BD/V1_0_0/TestCases/BD_SMOKE_001.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/BD/V1_0_0/TestCases/BD_SMOKE_001.class -------------------------------------------------------------------------------- /bin/com/sakura/base/StepAction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/base/StepAction.class -------------------------------------------------------------------------------- /bin/com/sakura/base/TestBase.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/base/TestBase.class -------------------------------------------------------------------------------- /bin/com/sakura/base/TestCase.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/base/TestCase.class -------------------------------------------------------------------------------- /bin/com/sakura/base/TestStep.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/base/TestStep.class -------------------------------------------------------------------------------- /bin/com/sakura/base/TestUnit.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/base/TestUnit.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/AndroidSystemHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/AndroidSystemHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/CheckActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/CheckActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/ClearActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/ClearActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/ClickActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/ClickActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/DBActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/DBActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/ExecuteShellHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/ExecuteShellHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/FileAction_Handler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/FileAction_Handler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/FileReaderHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/FileReaderHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/FreeSSH_FTP_Handler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/FreeSSH_FTP_Handler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/GetCodeActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/GetCodeActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/GetUrlActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/GetUrlActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/HttpRequestHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/HttpRequestHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/InputActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/InputActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/RecordActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/RecordActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/SetActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/SetActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/SlideActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/SlideActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/WaitActionHandler$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/WaitActionHandler$1.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/WaitActionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/WaitActionHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/handler/WindowsSystemHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/handler/WindowsSystemHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/service/AndroidXmlParseService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/service/AndroidXmlParseService.class -------------------------------------------------------------------------------- /bin/com/sakura/service/AppiumService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/service/AppiumService.class -------------------------------------------------------------------------------- /bin/com/sakura/service/ExtentReportGenerateService$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/service/ExtentReportGenerateService$1.class -------------------------------------------------------------------------------- /bin/com/sakura/service/ExtentReportGenerateService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/service/ExtentReportGenerateService.class -------------------------------------------------------------------------------- /bin/com/sakura/service/RunUnitService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/service/RunUnitService.class -------------------------------------------------------------------------------- /bin/com/sakura/service/WebXmlParseService.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/service/WebXmlParseService.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ANSIConsoleAppender.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ANSIConsoleAppender.class -------------------------------------------------------------------------------- /bin/com/sakura/util/AppiumUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/AppiumUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/CommandUtil$ResultHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/CommandUtil$ResultHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/util/CommandUtil$SimpleResultHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/CommandUtil$SimpleResultHandler.class -------------------------------------------------------------------------------- /bin/com/sakura/util/CommandUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/CommandUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ConfigUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ConfigUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ConnDatabase.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ConnDatabase.class -------------------------------------------------------------------------------- /bin/com/sakura/util/Constants.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/Constants.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ConstantsUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ConstantsUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/CopyFile.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/CopyFile.class -------------------------------------------------------------------------------- /bin/com/sakura/util/DBHelper$MyUserInfo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/DBHelper$MyUserInfo.class -------------------------------------------------------------------------------- /bin/com/sakura/util/DBHelper$OpType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/DBHelper$OpType.class -------------------------------------------------------------------------------- /bin/com/sakura/util/DBHelper.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/DBHelper.class -------------------------------------------------------------------------------- /bin/com/sakura/util/DBSSH.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/DBSSH.class -------------------------------------------------------------------------------- /bin/com/sakura/util/DateUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/DateUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ExcelHelper.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ExcelHelper.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ExcpUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ExcpUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ExecuteSSHToolUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ExecuteSSHToolUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ExecuteShellUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ExecuteShellUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/FileReaderUtil$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/FileReaderUtil$1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/FileReaderUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/FileReaderUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/FileUtil$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/FileUtil$1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/FileUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/FileUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/FreeSFTPUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/FreeSFTPUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/FreeSSHUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/FreeSSHUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/GetInfo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/GetInfo.class -------------------------------------------------------------------------------- /bin/com/sakura/util/HttpGetRequestUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/HttpGetRequestUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/HttpPostRequestUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/HttpPostRequestUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/HttpRequestUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/HttpRequestUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ImageUtil$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ImageUtil$1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ImageUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ImageUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/JSchUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/JSchUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/JsonUtil$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/JsonUtil$1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/JsonUtil$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/JsonUtil$2.class -------------------------------------------------------------------------------- /bin/com/sakura/util/JsonUtil$3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/JsonUtil$3.class -------------------------------------------------------------------------------- /bin/com/sakura/util/JsonUtil$4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/JsonUtil$4.class -------------------------------------------------------------------------------- /bin/com/sakura/util/JsonUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/JsonUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/Log4jUtil$BeginFileData.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/Log4jUtil$BeginFileData.class -------------------------------------------------------------------------------- /bin/com/sakura/util/Log4jUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/Log4jUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/MapUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/MapUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/MongoDBUtil$OperationType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/MongoDBUtil$OperationType.class -------------------------------------------------------------------------------- /bin/com/sakura/util/MongoDBUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/MongoDBUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/MongoDBUtil1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/MongoDBUtil1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/MouseUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/MouseUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ObsRemoteUtil$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ObsRemoteUtil$1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ObsRemoteUtil$ObsWebSocketEndpoint.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ObsRemoteUtil$ObsWebSocketEndpoint.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ObsRemoteUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ObsRemoteUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/OrderedProperties.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/OrderedProperties.class -------------------------------------------------------------------------------- /bin/com/sakura/util/PingUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/PingUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/RegexUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/RegexUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ScreenCaptureExample.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ScreenCaptureExample.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ScreenRecorderTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ScreenRecorderTest.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ScreenRecorderUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ScreenRecorderUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/SeleniumUtil$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/SeleniumUtil$1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/SeleniumUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/SeleniumUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/StringUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/StringUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/SystemOutUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/SystemOutUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/SystemUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/SystemUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/VideoRecorder$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/VideoRecorder$1.class -------------------------------------------------------------------------------- /bin/com/sakura/util/VideoRecorder$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/VideoRecorder$2.class -------------------------------------------------------------------------------- /bin/com/sakura/util/VideoRecorder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/VideoRecorder.class -------------------------------------------------------------------------------- /bin/com/sakura/util/ZipUtil.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/ZipUtil.class -------------------------------------------------------------------------------- /bin/com/sakura/util/maintest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/bin/com/sakura/util/maintest.class -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 95 | 96 | 97 | 101 | -------------------------------------------------------------------------------- /lib/DataBase/cache-jdbc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/DataBase/cache-jdbc.jar -------------------------------------------------------------------------------- /lib/DataBase/gbase8a-jdbc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/DataBase/gbase8a-jdbc.jar -------------------------------------------------------------------------------- /lib/DataBase/gbase8s-jdbc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/DataBase/gbase8s-jdbc.jar -------------------------------------------------------------------------------- /lib/DataBase/hive-jdbc-3.1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/DataBase/hive-jdbc-3.1.3.jar -------------------------------------------------------------------------------- /lib/DataBase/hive-jdbc-uber-2.6.5.0-292.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/DataBase/hive-jdbc-uber-2.6.5.0-292.jar -------------------------------------------------------------------------------- /lib/DataBase/ojdbc7-12.1.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/DataBase/ojdbc7-12.1.0.2.jar -------------------------------------------------------------------------------- /lib/DataBase/sybase-jdbc-jconn4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/DataBase/sybase-jdbc-jconn4.jar -------------------------------------------------------------------------------- /lib/Excel/jxl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/Excel/jxl.jar -------------------------------------------------------------------------------- /lib/Json/json-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/Json/json-2.0.jar -------------------------------------------------------------------------------- /lib/Log4j/log4j-1.2.16.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/Log4j/log4j-1.2.16.jar -------------------------------------------------------------------------------- /lib/Log4j/slf4j-api-1.6.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/Log4j/slf4j-api-1.6.6.jar -------------------------------------------------------------------------------- /lib/Log4j/slf4j-log4j12-1.6.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/Log4j/slf4j-log4j12-1.6.6.jar -------------------------------------------------------------------------------- /lib/Selenium/selenium-server-standalone-2.53.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/Selenium/selenium-server-standalone-2.53.0.jar -------------------------------------------------------------------------------- /lib/Tentng/testng-6.9.10.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/Tentng/testng-6.9.10.jar -------------------------------------------------------------------------------- /lib/TestReport/ExtentReport/extentreports-2.41.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/ExtentReport/extentreports-2.41.2.jar -------------------------------------------------------------------------------- /lib/TestReport/ExtentReport/extentreports-3.0.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/ExtentReport/extentreports-3.0.6.jar -------------------------------------------------------------------------------- /lib/TestReport/ExtentReport/extentreports-java-2.41.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/ExtentReport/extentreports-java-2.41.1.jar -------------------------------------------------------------------------------- /lib/TestReport/ExtentReport/freemarker-2.3.23.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/ExtentReport/freemarker-2.3.23.jar -------------------------------------------------------------------------------- /lib/TestReport/ExtentReport/guice-3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/ExtentReport/guice-3.0.jar -------------------------------------------------------------------------------- /lib/TestReport/ExtentReport/mongo-java-driver-3.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/ExtentReport/mongo-java-driver-3.3.0.jar -------------------------------------------------------------------------------- /lib/TestReport/TestngReport/reportng-1.1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/TestngReport/reportng-1.1.5.jar -------------------------------------------------------------------------------- /lib/TestReport/TestngReport/saxon-8.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/TestngReport/saxon-8.7.jar -------------------------------------------------------------------------------- /lib/TestReport/TestngReport/velocity-1.7-dep.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/lib/TestReport/TestngReport/velocity-1.7-dep.jar -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #@echo off 4 | #mvn clean package && ant 5 | 6 | # 1. 获取最近一次提交的commit ID 7 | last_commit=$(git rev-parse HEAD) 8 | echo "当前构建版本:$last_commit" 9 | echo "上一次构建版本:$(cat .last_commit)" 10 | # 2. 判断当前构建版本与上一次构建版本是否一致 11 | if [ -f .last_commit ] && [ "$(cat .last_commit)" = "$last_commit" ]; then 12 | echo "Git仓库没有新的提交,跳过编译打包操作" 13 | #mvn package 14 | else 15 | echo "Git仓库有新的提交,执行编译打包操作" 16 | mvn package 17 | # 保存当前构建版本到文件 18 | echo "$last_commit" > .last_commit 19 | fi -------------------------------------------------------------------------------- /src/main/java/com/sakura/base/TestBase.java: -------------------------------------------------------------------------------- 1 | package com.sakura.base; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import io.appium.java_client.android.AndroidDriver; 6 | import lombok.Data; 7 | import org.openqa.selenium.support.ui.WebDriverWait; 8 | 9 | /** 10 | *
对应于XML文件中的Case元素
11 | * 12 | * @version 1.0 13 | * @since 1.0 14 | */ 15 | @Data 16 | public class TestBase { 17 | 18 | private String id; 19 | 20 | private String name; 21 | 22 | private boolean cancel; 23 | 24 | private WebDriver webDriver; 25 | 26 | private WebDriverWait webDriverWait; 27 | 28 | private AndroidDriver AndroidDriver; 29 | 30 | // public String getId() { 31 | // return id; 32 | // } 33 | // 34 | // public void setId(String id) { 35 | // this.id = id; 36 | // } 37 | // 38 | // public String getName() { 39 | // return name; 40 | // } 41 | // 42 | // public void setName(String name) { 43 | // this.name = name; 44 | // } 45 | // 46 | // public boolean getCancel() { 47 | // return cancel; 48 | // } 49 | // 50 | // public void setCancel(boolean cancel) { 51 | // this.cancel = cancel; 52 | // } 53 | // 54 | // public WebDriver getWebDriver() { 55 | // return Wdriver; 56 | // } 57 | // 58 | // public void setWebDriver(WebDriver driver) { 59 | // this.Wdriver = driver; 60 | // } 61 | // 62 | // public AndroidDriver getAndroidDriver() { 63 | // return Adriver; 64 | // } 65 | // 66 | // public void setAndroidDriver(AndroidDriver driver) { 67 | // this.Adriver = driver; 68 | // } 69 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/base/TestCase.java: -------------------------------------------------------------------------------- 1 | package com.sakura.base; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Data; 6 | 7 | @Data 8 | public class TestCase extends TestBase{ 9 | 10 | private String id; 11 | 12 | private String name; 13 | 14 | private boolean cancel; 15 | 16 | private List steps; 17 | 18 | // public static String getid() { 19 | // return id; 20 | // } 21 | // 22 | // public void setid(String id) { 23 | // TestCase.id = id; 24 | // } 25 | // 26 | // public static String getname() { 27 | // return name; 28 | // } 29 | // 30 | // public void setname(String name) { 31 | // TestCase.name = name; 32 | // } 33 | // 34 | // public boolean isCancel() { 35 | // return cancel; 36 | // } 37 | // 38 | // public void setCancel(boolean cancel) { 39 | // this.cancel = cancel; 40 | // } 41 | // 42 | // public List getSteps() { 43 | // return steps; 44 | // } 45 | // 46 | // public void setSteps(List steps) { 47 | // this.steps = steps; 48 | // } 49 | // 50 | // public String getName() { 51 | // return super.getName(); 52 | // } 53 | 54 | @Override 55 | public String toString() { 56 | System.out.println("TestCase "+super.getName()+" [steps=" + steps + "]"); 57 | return "TestCase "+super.getName()+" [steps=" + steps + "]"; 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/base/TestUnit.java: -------------------------------------------------------------------------------- 1 | package com.sakura.base; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | import lombok.Data; 6 | 7 | /** 8 | *
对应于XML文件中的unit元素
9 | * 10 | * @version 1.0 11 | * @since 1.0 12 | */ 13 | @Data 14 | public class TestUnit { 15 | 16 | private String id; 17 | 18 | private String name; 19 | 20 | private LinkedHashMap caseMap; 21 | 22 | // public static String getId() { 23 | // return id; 24 | // } 25 | // 26 | // public void setId(String id) { 27 | // this.id = id; 28 | // } 29 | // 30 | // public static String getName() { 31 | // return name; 32 | // } 33 | // 34 | // public void setName(String name) { 35 | // this.name = name; 36 | // } 37 | // 38 | // public LinkedHashMap getCaseMap() { 39 | // return caseMap; 40 | // } 41 | // 42 | // public void setCaseMap(LinkedHashMap caseMap) { 43 | // this.caseMap = caseMap; 44 | // } 45 | 46 | @Override 47 | public String toString() { 48 | // System.out.println("TestUnit [caseMap=" + caseMap + "]"); 49 | return "TestUnit [caseMap=" + caseMap + "]"; 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/AndroidSystemHandler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import com.sakura.base.TestStep; 6 | 7 | import io.appium.java_client.TouchAction; 8 | import io.appium.java_client.android.AndroidDeviceActionShortcuts; 9 | 10 | public class AndroidSystemHandler { 11 | 12 | Logger log = Logger.getLogger(AndroidSystemHandler.class); 13 | 14 | /** 15 | *
模拟点击Android系统键盘按键操作,例如:KEYCODE_HOME 3
16 | * 17 | * @param step 18 | * @throws Exception 19 | */ 20 | public void androidKeycode(TestStep step) throws Exception { 21 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 22 | ((AndroidDeviceActionShortcuts) step.getAndroidDriver()). 23 | pressKeyCode(Integer.valueOf(step.getDetails().get("key"))); 24 | Thread.sleep(600); 25 | } 26 | 27 | /** 28 | *
模拟点击Android系统返回按键操作,可返回多次
29 | * 30 | * @param step 31 | * @throws Exception 32 | */ 33 | public void androidReturn(TestStep step) throws Exception { 34 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 35 | int Num = Integer.valueOf(step.getDetails().get("num")); 36 | for (int i = 0; i < Num; i++) { 37 | step.getAndroidDriver().navigate().back(); 38 | } 39 | } 40 | 41 | /** 42 | *
模拟打开Androud系统通知栏操作
43 | * 44 | * @param step 45 | * @throws Exception 46 | */ 47 | public void androidOpennb(TestStep step) throws Exception { 48 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 49 | step.getAndroidDriver().openNotifications(); 50 | } 51 | 52 | /** 53 | *
模拟执行Androud系统页面滚动操作
54 | * 55 | * @param step 56 | * @throws Exception 57 | */ 58 | public void androidScroll(TestStep step) throws Exception { 59 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 60 | step.getAndroidDriver().scrollToExact(step.getValue()).click(); 61 | } 62 | 63 | /** 64 | *
模拟执行Androud系统页面滑动操作
65 | * 66 | * @param step 67 | * @throws Exception 68 | */ 69 | public void androidSwipe(TestStep step) throws Exception { 70 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 71 | TouchAction tAction = new TouchAction(step.getAndroidDriver()); 72 | tAction.press(400,500).waitAction(800).moveTo(50,500).release().perform(); 73 | } 74 | 75 | /** 76 | *
Android-ADB指令模拟键盘操作
77 | * 78 | * keycode通过keycode表获取百度可查,home键的keycode=3,back键的keycode=4 79 | * @param step 80 | * @throws Exception 81 | */ 82 | public void adbKeycode(TestStep step) throws Exception{ 83 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 84 | Runtime.getRuntime().exec("adb -s "+step.getLocator()+" shell input keyevent "+ step.getValue()); 85 | } 86 | 87 | /** 88 | *
Android-ADB指令页面输入操作,先点击输入框
89 | * 90 | * @param step 91 | * @throws Exception 92 | */ 93 | public void adbInput(TestStep step) throws Exception{ 94 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 95 | Runtime.getRuntime().exec("adb -s "+step.getLocator()+" shell input text "+ step.getValue()); 96 | } 97 | 98 | /** 99 | *
Android-ADB指令页面坐标点击操作
100 | * 101 | * @param step 102 | * @throws Exception 103 | */ 104 | public void adbClick(TestStep step) throws Exception{ 105 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 106 | Runtime.getRuntime().exec("adb -s "+step.getLocator()+" shell input tap "+ step.getDetails().get("x") +" "+ step.getDetails().get("y")); 107 | } 108 | 109 | /** 110 | *
Android-ADB指令页面滑动操作
111 | * 112 | * @param step 113 | * @throws Exception 114 | */ 115 | public void adbSwipe(TestStep step) throws Exception{ 116 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 117 | Runtime.getRuntime().exec("adb -s "+step.getLocator()+" shell input swipe "+ step.getDetails().get("x1") +" "+ step.getDetails().get("y1")+ step.getDetails().get("x2") +" "+ step.getDetails().get("y2")); 118 | } 119 | 120 | /** 121 | *
Android-ADB切换输入法操作
122 | * 123 | * 通过adb shell ime list -s 命令,获取value值 124 | * @param step 125 | * @throws Exception 126 | */ 127 | public void adbIme(TestStep step) throws Exception{ 128 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 129 | Runtime.getRuntime().exec("adb -s "+step.getLocator()+" shell ime set "+ step.getValue()); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/ClearActionHandler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import com.sakura.service.RunUnitService; 4 | import org.apache.log4j.Logger; 5 | import org.openqa.selenium.Keys; 6 | import org.openqa.selenium.WebElement; 7 | 8 | import com.sakura.base.TestStep; 9 | import com.sakura.util.AppiumUtil; 10 | import com.sakura.util.SeleniumUtil; 11 | 12 | public class ClearActionHandler { 13 | Logger log = Logger.getLogger(ClearActionHandler.class); 14 | 15 | /** 16 | *
Web端清除操作
17 | * 18 | * @param step 19 | * @throws Exception 20 | */ 21 | public void webInputclear(TestStep step) throws Exception { 22 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 23 | RunUnitService.Step.put("name", step.getId() + "." + step.getName() + ">"); 24 | step.setType("elementToBeClickable"); 25 | WebElement e = SeleniumUtil.getElement(step); 26 | // e.clear(); 27 | 28 | // WebDriver driver = step.getWebDriver(); 29 | // Actions actions=new Actions(driver); 30 | // actions.doubleClick(e).perform(); 31 | // e.sendKeys(""); 32 | 33 | e.sendKeys(Keys.CONTROL,"a"); 34 | e.sendKeys(Keys.DELETE); 35 | } 36 | 37 | /** 38 | *
Android端清除操作
39 | * 40 | * @param step 41 | * @throws Exception 42 | */ 43 | public void androidClear(TestStep step) throws Exception { 44 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 45 | WebElement e = AppiumUtil.getElement(step); 46 | e.clear(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/ExecuteShellHandler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import com.sakura.base.TestStep; 6 | import com.sakura.service.RunUnitService; 7 | import com.sakura.util.ConfigUtil; 8 | import com.sakura.util.Constants; 9 | import com.sakura.util.ExecuteShellUtil; 10 | import com.sakura.util.SeleniumUtil; 11 | import com.sakura.util.StringUtil; 12 | import com.sakura.util.ExecuteSSHToolUtil; 13 | 14 | /** 15 | * 连接Linux执行shell命令 16 | */ 17 | public class ExecuteShellHandler { 18 | Logger log = Logger.getLogger(getClass()); 19 | 20 | public void exeShell(TestStep step) throws Exception{ 21 | // String Device = step.getDevice(); 22 | String Shell = SeleniumUtil.parseStringHasEls(step.getShell()); 23 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">["+ Shell +"]"); 24 | 25 | String host = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_IP", Constants.CONFIG_APP); 26 | int port = Integer.parseInt(ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_Port", Constants.CONFIG_APP)); 27 | String username = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_UserName", Constants.CONFIG_APP); 28 | String password = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_PassWord", Constants.CONFIG_APP); 29 | 30 | ExecuteSSHToolUtil executeShellUtil = new ExecuteSSHToolUtil(); 31 | executeShellUtil.init(host,port,username,password); 32 | String result = executeShellUtil.execCmd(Shell); 33 | if(step.getRegex()!=null) { 34 | result = StringUtil.getRegex(result,step.getRegex()); 35 | } 36 | if(step.getKey()!=null) { 37 | result = StringUtil.replaceAllBlank(result, step.getKey(), step.getValue()); 38 | } 39 | if(step.getDetails()!=null) { 40 | SeleniumUtil.localmap.put(step.getDetails().get("key"), result); 41 | log.info("『正常测试』开始执行: <成功记录到本地List列表," + SeleniumUtil.localmap.toString() + ">"); 42 | } 43 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ">["+ Shell +"]"); 44 | } 45 | 46 | public void exeShell1(TestStep step) throws Exception{ 47 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 48 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ""); 49 | // String Device = step.getDevice(); 50 | String Shell = step.getShell(); 51 | 52 | String host = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_IP", Constants.CONFIG_APP); 53 | int port = Integer.parseInt(ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_Port", Constants.CONFIG_APP)); 54 | String username = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_UserName", Constants.CONFIG_APP); 55 | String password = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_PassWord", Constants.CONFIG_APP); 56 | 57 | ExecuteShellUtil executeShellUtil = new ExecuteShellUtil(host,port,username,password); 58 | String result = executeShellUtil.executeForResult(Shell); 59 | // log.info(result); 60 | log.info("『正常测试』执行成功: " + "<" + result + ">"); 61 | executeShellUtil.close(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/FileAction_Handler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import java.util.List; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | import com.sakura.util.ZipUtil; 8 | import org.apache.log4j.Logger; 9 | 10 | import com.sakura.base.TestStep; 11 | import com.sakura.service.RunUnitService; 12 | import com.sakura.util.FileUtil; 13 | import com.sakura.util.SeleniumUtil; 14 | 15 | /** 16 | * 上传本地文件到服务器 17 | */ 18 | public class FileAction_Handler { 19 | Logger log = Logger.getLogger(getClass()); 20 | 21 | public void getFile(TestStep step) throws Exception{ 22 | String value = SeleniumUtil.parseStringHasEls(step.getLocalpath()); 23 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">["+ value +"]"); 24 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ">["+ value +"]"); 25 | value = FileUtil.getFileList(value).get(0).get(step.getDetails().get("key")).toString(); 26 | SeleniumUtil.localmap.put(step.getDetails().get("keys"), value); 27 | log.info("『正常测试』开始执行: <成功记录到本地List列表," + SeleniumUtil.localmap.toString() + ">"); 28 | } 29 | 30 | public void getFiles(TestStep step) throws Exception{ 31 | String value; 32 | if(step.getCatalogue()!=null) { 33 | value = SeleniumUtil.parseStringHasEls(System.getProperty(step.getCatalogue())+step.getLocalpath()); 34 | }else { 35 | value = SeleniumUtil.parseStringHasEls(System.getProperty("user.dir")+step.getLocalpath()); 36 | } 37 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">["+ value +"]"); 38 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ">["+ value +"]"); 39 | value = FileUtil.getFileList(value).get(0).get(step.getDetails().get("key")).toString(); 40 | SeleniumUtil.localmap.put(step.getDetails().get("keys"), value); 41 | log.info("『正常测试』开始执行: <成功记录到本地List列表," + SeleniumUtil.localmap.toString() + ">"); 42 | } 43 | 44 | public void deleteFile(TestStep step) throws Exception{ 45 | String value = SeleniumUtil.parseStringHasEls(step.getLocalpath()); 46 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">["+ value +"]"); 47 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ">["+ value +"]"); 48 | if(step.getDelete()!=null) { 49 | FileUtil.deleteAllFile(value,step.getDelete()); 50 | }else { 51 | FileUtil.deleteAllFile(value); 52 | } 53 | } 54 | 55 | public void deleteFiles(TestStep step) throws Exception{ 56 | String value = ""; 57 | if(step.getCatalogue()!=null) { 58 | value = SeleniumUtil.parseStringHasEls(System.getProperty(step.getCatalogue())+step.getLocalpath()); 59 | }else { 60 | value = SeleniumUtil.parseStringHasEls(System.getProperty("user.dir")+step.getLocalpath()); 61 | } 62 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">["+ value +"]"); 63 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ">["+ value +"]"); 64 | if(step.getDelete()!=null) { 65 | FileUtil.deleteAllFile(value,step.getDelete()); 66 | }else { 67 | FileUtil.deleteAllFile(value); 68 | } 69 | } 70 | 71 | public void zipFile(TestStep step) throws Exception{ 72 | String localpath = ""; 73 | String remotepath = ""; 74 | String result = ""; 75 | if(step.getCatalogue()!=null) { 76 | localpath = SeleniumUtil.parseStringHasEls(System.getProperty(step.getCatalogue())+step.getLocalpath()); 77 | remotepath = SeleniumUtil.parseStringHasEls(System.getProperty(step.getCatalogue())+step.getRemotepath()); 78 | }else { 79 | localpath = SeleniumUtil.parseStringHasEls(step.getLocalpath()); 80 | remotepath = SeleniumUtil.parseStringHasEls(step.getRemotepath()); 81 | } 82 | if(step.getType().equals("压缩文件")) { 83 | ZipUtil.toZip(localpath,remotepath); 84 | result = step.getRemotepath(); 85 | }else if(step.getType().equals("解压文件")) { 86 | List fileNames = ZipUtil.unzip(localpath,remotepath); 87 | if(step.getRegex()!=null) { 88 | // 正则表达式模式,用于匹配文件名中的序号 89 | Pattern pattern = Pattern.compile(step.getRegex()); 90 | // 遍历文件名列表,查找指定序号的文件名 91 | for (String name : fileNames) { 92 | Matcher matcher = pattern.matcher(name); 93 | if (matcher.find()) { 94 | result = name; 95 | } 96 | } 97 | }else{ 98 | result = fileNames.get(Integer.parseInt(step.getValue())); 99 | } 100 | } 101 | if(step.getDelete()!=null) { 102 | FileUtil.deleteAllFile(localpath,step.getDelete()); 103 | }else { 104 | FileUtil.deleteAllFile(localpath); 105 | } 106 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">["+ result +"]"); 107 | RunUnitService.Step.put("name", step.getId() + "." + step.getName() + ">["+ result +"]"); 108 | SeleniumUtil.localmap.put(step.getDetails().get("key"), result); 109 | log.info("『正常测试』开始执行: <成功记录到本地List列表," + SeleniumUtil.localmap.toString() + ">"); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/FileReaderHandler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import com.sakura.base.TestStep; 4 | import com.sakura.util.AppiumUtil; 5 | import com.sakura.util.FileReaderUtil; 6 | import com.sakura.util.SeleniumUtil; 7 | import org.apache.log4j.Logger; 8 | import org.openqa.selenium.Keys; 9 | import org.openqa.selenium.WebElement; 10 | 11 | public class FileReaderHandler { 12 | Logger log = Logger.getLogger(FileReaderHandler.class); 13 | 14 | /** 15 | *
Web端清除操作
16 | * 17 | * @param step 18 | * @throws Exception 19 | */ 20 | public void webInputclear(TestStep step) throws Exception { 21 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 22 | FileReaderUtil.readFileContent(step.getLocalpath(), step.getFiletype()); 23 | } 24 | 25 | /** 26 | *
Android端清除操作
27 | * 28 | * @param step 29 | * @throws Exception 30 | */ 31 | public void androidClear(TestStep step) throws Exception { 32 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 33 | WebElement e = AppiumUtil.getElement(step); 34 | e.clear(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/FreeSSH_FTP_Handler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import com.sakura.base.TestStep; 6 | import com.sakura.service.RunUnitService; 7 | import com.sakura.util.ConfigUtil; 8 | import com.sakura.util.Constants; 9 | import com.sakura.util.FreeSFTPUtil; 10 | import com.sakura.util.SeleniumUtil; 11 | import com.sakura.util.StringUtil; 12 | 13 | import java.util.Objects; 14 | 15 | /** 16 | * 上传本地文件到服务器 17 | */ 18 | public class FreeSSH_FTP_Handler { 19 | Logger log = Logger.getLogger(getClass()); 20 | 21 | public void freeSftp(TestStep step) throws Exception{ 22 | String host = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_IP", Constants.CONFIG_APP); 23 | int port = Integer.parseInt(Objects.requireNonNull(ConfigUtil.getProperty("" + step.getDevice() + "_LinuxShell_Port", Constants.CONFIG_APP))); 24 | String username = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_UserName", Constants.CONFIG_APP); 25 | String password = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_PassWord", Constants.CONFIG_APP); 26 | 27 | FreeSFTPUtil ftp = new FreeSFTPUtil(host,port,username,password); 28 | String localPath = SeleniumUtil.parseStringHasEls(step.getLocalpath()); 29 | String value = SeleniumUtil.parseStringHasEls(step.getValue()); 30 | String remotePath = step.getRemotepath(); 31 | 32 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." + step.getName() + ">["+localPath+value+"]"); 33 | RunUnitService.Step.put("name", step.getId() + "." + step.getName() + ">["+localPath+value+"]"); 34 | 35 | ftp.connect(); 36 | boolean result = false; 37 | if(StringUtil.isEqual(step.getFiletype(),"单个文件")){ 38 | result = ftp.uploadFile(localPath,value,remotePath,value,Boolean.parseBoolean(step.getDelete())); 39 | } else { 40 | result = ftp.bacthUploadFile(localPath,remotePath,Boolean.parseBoolean(step.getDelete())); 41 | } 42 | ftp.listFiles(remotePath); 43 | ftp.disconnect(); 44 | } 45 | 46 | public void freeSftps(TestStep step) throws Exception{ 47 | String host = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_IP", Constants.CONFIG_APP); 48 | int port = Integer.parseInt(ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_Port", Constants.CONFIG_APP)); 49 | String username = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_UserName", Constants.CONFIG_APP); 50 | String password = ConfigUtil.getProperty(""+step.getDevice()+"_LinuxShell_PassWord", Constants.CONFIG_APP); 51 | FreeSFTPUtil ftp = new FreeSFTPUtil(host,port,username,password); 52 | String localPath=""; 53 | if(step.getCatalogue()!=null) { 54 | localPath = SeleniumUtil.parseStringHasEls(System.getProperty(step.getCatalogue()) + step.getLocalpath()); 55 | }else { 56 | localPath = SeleniumUtil.parseStringHasEls(System.getProperty("user.dir") + step.getLocalpath()); 57 | } 58 | String value = SeleniumUtil.parseStringHasEls(step.getValue()); 59 | String remotePath = step.getRemotepath(); 60 | 61 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." + step.getName() + ">["+localPath+value+"]"); 62 | RunUnitService.Step.put("name", step.getId() + "." + step.getName() + ">["+localPath+value+"]"); 63 | 64 | ftp.connect(); 65 | boolean result = false; 66 | if(StringUtil.isEqual(step.getFiletype(),"单个文件")){ 67 | result = ftp.uploadFile(localPath,value,remotePath,value,Boolean.parseBoolean(step.getDelete())); 68 | } else { 69 | result = ftp.bacthUploadFile(localPath,remotePath,Boolean.parseBoolean(step.getDelete())); 70 | } 71 | ftp.listFiles(remotePath); 72 | ftp.disconnect(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/HttpRequestHandler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import java.util.Map; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import com.sakura.base.TestStep; 8 | import com.sakura.service.RunUnitService; 9 | import com.sakura.util.HttpRequestUtil; 10 | import com.sakura.util.SeleniumUtil; 11 | 12 | /** 13 | * http请求动作处理类 14 | */ 15 | public class HttpRequestHandler { 16 | Logger log = Logger.getLogger(HttpRequestHandler.class); 17 | 18 | /** 19 | *指定API接口URL,获取Cookie 20 | * @param map 21 | * @param step 22 | * @throws Exception 23 | */ 24 | @SuppressWarnings("unused") 25 | public void getCookie(TestStep step) throws Exception{ 26 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 27 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ""); 28 | // String ApiUrl = ConfigUtil.getProperty("test.api."+step.getUrl()+"", Constants.CONFIG_COMMON); 29 | String ApiUrl = step.getUrl(); 30 | String Param = "{\"userId\": \"666666\",\"password\": \"612426\",\"type\": \"string\",\"version\": \"string\",\"identification\": \"string\"}"; 31 | Map CookieVal =HttpRequestUtil.GetPostCookie(ApiUrl,Param); 32 | } 33 | 34 | /** 35 | * 指定API接口URL,发送POST请求 36 | * @param map 37 | * @param step 38 | * @throws Exception 39 | */ 40 | public void sendPost(TestStep step) throws Exception{ 41 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 42 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ""); 43 | // String ApiUrl = ConfigUtil.getProperty("test.api."+step.getUrl()+"", Constants.CONFIG_COMMON); 44 | String ApiUrl = step.getUrl(); 45 | String Param = "{\""+step.getBody()+"\": \""+SeleniumUtil.parseStringHasEls(step.getValue())+"\"}"; 46 | HttpRequestUtil.SendPost(ApiUrl,Param); 47 | // log.info("接口详情:" + ApiUrl+" "+Param); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/RecordActionHandler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import com.sakura.base.TestStep; 8 | import com.sakura.util.ConfigUtil; 9 | import com.sakura.util.Constants; 10 | 11 | /** 12 | *
录屏操作
13 | * 14 | * @author 505719 15 | * @email 刘智 16 | * @date 2017年8月14日11:39:50 17 | * @version 1.0 18 | * @since 1.0 19 | */ 20 | public class RecordActionHandler { 21 | Logger log = Logger.getLogger(RecordActionHandler.class); 22 | 23 | /** 24 | *
开始录制视频
25 | * 26 | * @param RecordCaseName 27 | */ 28 | public void startRecord(TestStep step) throws Exception { 29 | Runtime rt = Runtime.getRuntime(); 30 | String RecordCaseName = step.getCaseid(); 31 | try { 32 | rt.exec("cmd.exe /C adb shell screenrecord /sdcard/"+ RecordCaseName +".mp4"); 33 | log.info(step.getName()); 34 | } 35 | catch (IOException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | /** 41 | *
结束录制视频
42 | * 43 | */ 44 | public void endRecord(TestStep step) throws Exception { 45 | Runtime rt = Runtime.getRuntime(); 46 | try { 47 | rt.exec("cmd.exe /C adb kill-server"); 48 | rt.exec("cmd.exe /C adb start-server"); 49 | Thread.sleep(8000); 50 | log.info(step.getName()); 51 | } 52 | catch (IOException e) { 53 | e.printStackTrace(); 54 | } 55 | } 56 | 57 | /** 58 | *
上传录制的视频
59 | * 60 | * @param RecordCaseName 61 | */ 62 | public void pullRecord(TestStep step) throws Exception { 63 | Runtime rt = Runtime.getRuntime(); 64 | String RecordCaseName = step.getCaseid(); 65 | try { 66 | rt.exec("cmd.exe /C adb pull /sdcard/"+ RecordCaseName +".mp4"); 67 | Thread.sleep(3000); 68 | log.info(step.getName()); 69 | } 70 | catch (IOException e) { 71 | e.printStackTrace(); 72 | log.info("file not found"); 73 | } 74 | } 75 | 76 | /** 77 | *
移动录制的视频
78 | * 79 | * @param RecordCaseName 80 | */ 81 | public void moveRecord(TestStep step) throws Exception { 82 | Runtime rt = Runtime.getRuntime(); 83 | String RecordCaseName = step.getCaseid(); 84 | try { 85 | rt.exec("cmd.exe /C move "+ RecordCaseName +".mp4 " + ConfigUtil.getProperty("video.path", Constants.CONFIG_COMMON)); 86 | log.info(step.getName()); 87 | } 88 | catch (IOException e) { 89 | e.printStackTrace(); 90 | log.info("file not found"); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/handler/WaitActionHandler.java: -------------------------------------------------------------------------------- 1 | package com.sakura.handler; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import com.sakura.util.SeleniumUtil; 6 | import com.sakura.util.StringUtil; 7 | import org.apache.log4j.Logger; 8 | import org.openqa.selenium.By; 9 | import org.openqa.selenium.TimeoutException; 10 | import org.openqa.selenium.WebDriver; 11 | import org.openqa.selenium.WebElement; 12 | import org.openqa.selenium.support.ui.ExpectedCondition; 13 | import org.openqa.selenium.support.ui.ExpectedConditions; 14 | import org.openqa.selenium.support.ui.WebDriverWait; 15 | import org.testng.Assert; 16 | 17 | import com.sakura.base.TestStep; 18 | import com.sakura.service.RunUnitService; 19 | 20 | /** 21 | * 等待动作处理类 22 | */ 23 | public class WaitActionHandler { 24 | static Logger log = Logger.getLogger(WaitActionHandler.class); 25 | 26 | /** 27 | * 强制等待 28 | * @param map 29 | * @param step 30 | */ 31 | public static void waitForced(TestStep step){ 32 | try { 33 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 34 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ""); 35 | int waitTime = Integer.parseInt(step.getValue())/1000; 36 | if(waitTime>=1) { 37 | for(int i=waitTime;i>0;i--) { 38 | log.info("『正常测试』开始执行: " + "倒计时<"+i+"s>"); 39 | Thread.sleep(1000); 40 | } 41 | }else { 42 | Thread.sleep(waitTime*1000); 43 | } 44 | } catch (InterruptedException e) { 45 | Thread.currentThread().interrupt(); 46 | } 47 | } 48 | 49 | /** 50 | * Web端隐式等待 51 | * @param map 52 | * @param step 53 | */ 54 | public void webImplicit(TestStep step){ 55 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 56 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ""); 57 | long waitTime = Long.valueOf(step.getValue()); 58 | step.getWebDriver().manage().timeouts().implicitlyWait(waitTime, TimeUnit.SECONDS); 59 | } 60 | 61 | /** 62 | * Web端显示等待 63 | * @param map 64 | * @param step 65 | */ 66 | public void webDisplay(TestStep step) throws Exception { 67 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 68 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ""); 69 | 70 | String loc = step.getLocator(); 71 | if (StringUtil.isBlank(loc)) throw new Exception("当前步骤未定位到任何控件元素!"); 72 | int idx1 = loc.indexOf("="); 73 | String locatename = loc.substring(0, idx1); 74 | String locatevalue = loc.substring(idx1 + 1); 75 | locatevalue = SeleniumUtil.parseStringHasEls(locatevalue); 76 | 77 | WebDriverWait wait = new WebDriverWait(step.getWebDriver(), 10,500); 78 | //通过wait.until里面的方法找到元素 79 | if(locatename.equals("xpath")){ 80 | // 等待元素是否被加载在DOM中,并不代表该元素一定可见 81 | // wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(locatevalue))); 82 | // 等待元素是否可见(非隐藏,并且元素的宽和高都不等以0) 83 | wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locatevalue))); 84 | } 85 | // WebElement weekelement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(locatevalue))); 86 | // //执行点击或者输入值操作 87 | // weekelement.click(); 88 | } 89 | 90 | /** 91 | * Android端隐式等待 92 | * @param map 93 | * @param step 94 | */ 95 | public void androidImplicit(TestStep step){ 96 | log.info("『正常测试』开始执行: " + "<" +step.getId() + "." +step.getName() + ">"); 97 | RunUnitService.Step.put("name","" + step.getId() + "." + step.getName() + ""); 98 | long waitTime = Long.valueOf(step.getValue()); 99 | step.getAndroidDriver().manage().timeouts().implicitlyWait(waitTime, TimeUnit.SECONDS); 100 | } 101 | 102 | /** 103 | * 在给定的时间内去查找元素,如果没找到则超时,抛出异常 104 | * */ 105 | public static void waitForElementToLoad(WebDriver driver, int timeOut, final By By) { 106 | try { 107 | (new WebDriverWait(driver, timeOut)).until(new ExpectedCondition() { 108 | 109 | public Boolean apply(WebDriver driver) { 110 | WebElement element = driver.findElement(By); 111 | return element.isDisplayed(); 112 | } 113 | }); 114 | } catch (TimeoutException e) { 115 | Assert.fail("超时!! " + timeOut + " 秒之后还没找到元素 [" + By + "]"); 116 | } 117 | } 118 | 119 | //定义一个显式等待元素定位的方法,presenceOfElementLocated方法能保证元素出现在dom树上,但不能保证可见 120 | public WebElement getElement(TestStep step,By by,long outtime){ 121 | //显式等待,new WebDriverWait 里面要传一个驱动对象,然后是超时时间,以秒为单位,后面是轮询时间(默认是500毫秒),以毫秒为单位 122 | WebDriverWait wait = new WebDriverWait(step.getWebDriver(), outtime); 123 | try { 124 | WebElement weekelement = wait.until(ExpectedConditions.presenceOfElementLocated(by)); 125 | return weekelement; 126 | } catch (Exception e) { 127 | System.out.println("定位元素超时"); 128 | return null; 129 | } 130 | } 131 | //所以需要再加一个获取一个可见元素方法 132 | public WebElement getVibileElement(TestStep step,By by){ 133 | //显式等待,new WebDriverWait 里面要传一个驱动对象,然后是超时时间,以秒为单位,后面是轮询时间(默认是500毫秒),以毫秒为单位 134 | WebDriverWait wait = new WebDriverWait(step.getWebDriver(), 30); 135 | try { 136 | WebElement weekelement = wait.until(ExpectedConditions.visibilityOfElementLocated(by)); 137 | return weekelement; 138 | } catch (Exception e) { 139 | System.out.println("定位元素超时"); 140 | return null; 141 | } 142 | } 143 | 144 | //定义一个显式等待页面加载完成的方法 145 | public WebElement getpagereadyElement(TestStep step,By by){ 146 | //显式等待,new WebDriverWait 里面要传一个驱动对象,然后是超时时间,以秒为单位,后面是轮询时间(默认是500毫秒),以毫秒为单位 147 | WebDriverWait wait = new WebDriverWait(step.getWebDriver(), 30); 148 | try { 149 | String jsToBeExecute = "return document.readyState == 'complete'"; 150 | Boolean isready = (Boolean) wait.until(ExpectedConditions.jsReturnsValue(jsToBeExecute)); 151 | if (isready){ 152 | return getVibileElement(step,by); 153 | } 154 | } catch (Exception e) { 155 | System.out.println("页面加载超时"); 156 | } 157 | return null; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/service/AppiumService.java: -------------------------------------------------------------------------------- 1 | package com.sakura.service; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.apache.log4j.Logger; 7 | import org.openqa.selenium.WebElement; 8 | 9 | import com.sakura.util.ConfigUtil; 10 | import com.sakura.util.Constants; 11 | import com.sakura.util.FreeSSHUtil; 12 | import com.sakura.util.StringUtil; 13 | 14 | import io.appium.java_client.android.AndroidDriver; 15 | 16 | public class AppiumService { 17 | 18 | static Logger log = Logger.getLogger(AppiumService.class); 19 | 20 | AndroidDriver driver; 21 | public static String DeviceID; 22 | 23 | public static void appiumStop(String IP, String UserName, String PassWord) throws IOException, InterruptedException { 24 | // 创建或删除taskmgr计划任务,获取任务管理器的system权限 25 | // Runtime.getRuntime().exec("schtasks /create /tn taskmgr /sc daily /st 00:01 /tr taskmgr.exe"); 26 | // Runtime.getRuntime().exec("schtasks /f /delete /tn taskmgr"); 27 | 28 | // 强制结束node.exe进程 29 | try { 30 | if (StringUtil.isEqual(ConfigUtil.getProperty("Environment_Type", Constants.CONFIG_APP), "Linux")) { 31 | log.info("Appium服务关闭中,耐心等待ing..."); 32 | FreeSSHUtil.cmd(IP, UserName, PassWord, "taskkill /f /IM node.exe"); 33 | } else { 34 | log.info("Appium服务关闭中,耐心等待ing..."); 35 | cmd("taskkill /f /IM node.exe"); 36 | log.info("关闭所有cmd窗口..."); 37 | cmd("wmic process where name='cmd.exe' call terminate"); 38 | } 39 | Thread.sleep(500); 40 | } catch (Exception e) { 41 | log.info("Appium服务启动失败,请检查服务配置!"); 42 | //e.printStackTrace(); 43 | log.error("",e); 44 | } 45 | } 46 | 47 | public static void killProcess(String IP, String UserName, String PassWord) { 48 | try { 49 | if (StringUtil.isEqual(ConfigUtil.getProperty("Environment_Type", Constants.CONFIG_APP), "Linux")) { 50 | log.info("关闭所有cmd窗口..."); 51 | FreeSSHUtil.cmd(IP, UserName, PassWord, "wmic process where name='cmd.exe' call terminate"); 52 | } else { 53 | log.info("关闭所有cmd窗口..."); 54 | cmd("wmic process where name='cmd.exe' call terminate"); 55 | } 56 | Thread.sleep(500); 57 | } catch (Exception e) { 58 | log.info("Appium服务启动失败,请检查服务配置!"); 59 | //e.printStackTrace(); 60 | log.error("",e); 61 | } 62 | } 63 | 64 | public static void appiumStart(String IP, String Prot, String UserName, String PassWord, String Device) throws InterruptedException { 65 | try { 66 | // String AppiumStart = "cmd.exe /c start TestData/Appium/Appium.bat"); 67 | // 多设备server端需要手动指定每台设备的udid,安卓无线连接下就是设备的ip:port.. 68 | // String AppiumStart = "appium.cmd -p 4723 -bp 4724 --session-override --chromedriver-port 9515 -U 69 | // 10.18.88.33:8888 >C:/Users/King-liu/Desktop/4723.txt"; 70 | 71 | if (StringUtil.isEqual(ConfigUtil.getProperty("Environment_Type", Constants.CONFIG_APP), "Linux")) { 72 | DeviceID = Device; 73 | String AppiumStart = 74 | "node C:/Users/" + UserName + "/AppData/Local/Programs/Appium/resources/app/node_modules/appium/build/lib/main.js --address " + IP + " --port " + Prot + ">D:/appium.txt"; 75 | log.info("Appium服务启动中,耐心等待ing..."); 76 | FreeSSHUtil.cmd(IP, UserName, PassWord, AppiumStart); 77 | } else { 78 | String AppointLog = System.getProperty("user.dir") + "/Logs"; 79 | String AppiumStart = "node C:/Users/" + UserName + "/AppData/Local/Programs/Appium/resources/app/node_modules/appium/build/lib/main.js --address " + IP + " --port " + Prot + ">" 80 | + AppointLog + "/appium.txt"; 81 | File file = new File(AppointLog); 82 | if (!file.exists()) { 83 | file.mkdir(); 84 | log.info("创建目录:" + file); 85 | } 86 | log.info("Appium服务启动中,耐心等待ing..."); 87 | cmd(AppiumStart); 88 | } 89 | Thread.sleep(5000); 90 | if (StringUtil.isEqual(ConfigUtil.getProperty("" + Device + "_Type", Constants.CONFIG_APP), "WIFI")) { 91 | log.info("Appium服务启动成功,开始连接手机设备..."); 92 | FreeSSHUtil.cmd(IP, UserName, PassWord, "adb tcpip 8888"); 93 | FreeSSHUtil.cmd(IP, UserName, PassWord, "adb disconnect"); 94 | FreeSSHUtil.cmd(IP, UserName, PassWord, "adb connect " + ConfigUtil.getProperty("" + Device + "_DeviceID", Constants.CONFIG_APP) + ""); 95 | } 96 | log.info("<--------------------------------------------------------------------------------------------------------------------------------------->"); 97 | } catch (Exception e) { 98 | log.info("Appium服务启动失败,请检查服务配置!"); 99 | //e.printStackTrace(); 100 | log.error("",e); 101 | } 102 | } 103 | 104 | public static void cmd(String cmd) { 105 | try { 106 | log.info("cmd /c " + cmd); 107 | Runtime.getRuntime().exec("cmd /c " + cmd); 108 | // Process pr = Runtime.getRuntime().exec(cmd); 109 | // BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream(), "utf-8")); 110 | // String line = input.readLine(); 111 | // if (line != null) { 112 | // while (line != null) { 113 | // line = input.readLine(); 114 | // log.info(line); 115 | // } 116 | // } 117 | } catch (IOException e) { 118 | //e.printStackTrace(); 119 | log.error("",e); 120 | } 121 | } 122 | 123 | public static void StartAppium(String IP, String Prot, String UserName, String PassWord, String Device) { 124 | try { 125 | appiumStop(IP, UserName, PassWord); 126 | killProcess(IP, UserName, PassWord); 127 | appiumStart(IP, Prot, UserName, PassWord, Device); 128 | } catch (IOException | InterruptedException e) { 129 | //e.printStackTrace(); 130 | log.error("",e); 131 | } 132 | } 133 | 134 | public static void main(String[] args) throws IOException, InterruptedException { 135 | // StartAppium("10.18.22.32", "4723", "King-liu", "111111", "MI_8"); 136 | StartAppium("10.18.22.65", "4723", "Administrator", "111111", "MI_9"); 137 | 138 | } 139 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ANSIConsoleAppender.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import org.apache.log4j.ConsoleAppender; 4 | import org.apache.log4j.Level; 5 | import org.apache.log4j.Logger; 6 | import org.apache.log4j.Priority; 7 | import org.apache.log4j.spi.LoggingEvent; 8 | 9 | /** 10 | * Colour-coded console appender for Log4J. 11 | */ 12 | @SuppressWarnings("unused") 13 | public class ANSIConsoleAppender extends ConsoleAppender { 14 | 15 | static Logger log = Logger.getLogger(ANSIConsoleAppender.class); 16 | 17 | private static final int NORMAL = 1; 18 | private static final int BRIGHT = 1; 19 | private static final int FOREGROUND_BLACK = 30; 20 | private static final int FOREGROUND_RED = 31; 21 | private static final int FOREGROUND_GREEN = 32; 22 | private static final int FOREGROUND_YELLOW = 33; 23 | private static final int FOREGROUND_BLUE = 34; 24 | private static final int FOREGROUND_MAGENTA = 35; 25 | private static final int FOREGROUND_CYAN = 36; 26 | private static final int FOREGROUND_WHITE = 37; 27 | 28 | private static final String PREFIX = "\u001b["; 29 | private static final String SUFFIX = "m] > "; 30 | private static final char SEPARATOR = ';'; 31 | private static final String END_COLOUR = PREFIX + SUFFIX; 32 | 33 | private static final String FATAL_COLOUR = PREFIX + BRIGHT + SEPARATOR + FOREGROUND_RED + SUFFIX; 34 | private static final String ERROR_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_RED + SUFFIX; 35 | private static final String WARN_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_YELLOW + SUFFIX; 36 | private static final String INFO_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_GREEN + SUFFIX; 37 | private static final String DEBUG_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_CYAN + SUFFIX; 38 | private static final String TRACE_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_BLUE + SUFFIX; 39 | 40 | /** 41 | * Wraps the ANSI control characters around the output from the super-class Appender. 42 | */ 43 | @Override 44 | public void append(LoggingEvent event) { 45 | this.qw.write(getColour(event.getLevel())); 46 | super.append(event); 47 | this.qw.write(END_COLOUR); 48 | 49 | if (this.immediateFlush) { 50 | this.qw.flush(); 51 | } 52 | } 53 | 54 | /** 55 | * Get the appropriate control characters to change the colour for the specified logging level. 56 | */ 57 | private String getColour(Level level) { 58 | switch (level.toInt()) { 59 | case Priority.FATAL_INT: 60 | return FATAL_COLOUR; 61 | case Priority.ERROR_INT: 62 | return ERROR_COLOUR; 63 | case Priority.WARN_INT: 64 | return WARN_COLOUR; 65 | case Priority.INFO_INT: 66 | return INFO_COLOUR; 67 | case Priority.DEBUG_INT: 68 | return DEBUG_COLOUR; 69 | default: 70 | return TRACE_COLOUR; 71 | } 72 | } 73 | 74 | public static void main(String[] args) { 75 | log.info("info"); 76 | log.error("error"); 77 | log.debug("debug"); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/CommandUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.io.*; 4 | 5 | import org.apache.log4j.Logger; 6 | public class CommandUtil { 7 | 8 | static Logger log = Logger.getLogger(CommandUtil.class); 9 | 10 | /** 11 | * 执行命令行操作,并返回执行结果。 12 | * 13 | * @param command 命令行参数数组。 14 | * @param workingDir 工作目录路径(可选)。 15 | * @param resultHandler 处理命令执行结果的回调接口。 16 | */ 17 | public static void executeCommand(String command, String workingDir, ResultHandler resultHandler) { 18 | try { 19 | // 创建Process实例 20 | log.info("Start Executed Command:"+command); 21 | Process process = Runtime.getRuntime().exec(command, null, workingDir == null ? null : new File(workingDir)); 22 | 23 | // 读取输出流,使用cp936编码,解决中文乱码问题 24 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "cp936")); 25 | PrintWriter writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream())); 26 | 27 | // 使用异步线程读取输出流 28 | Thread outputReaderThread = new Thread(() -> { 29 | String line; 30 | try { 31 | while ((line = reader.readLine()) != null) { 32 | // 调用回调接口处理输出 33 | resultHandler.onOutput(line); 34 | } 35 | } catch (Exception e) { 36 | resultHandler.onError("Error reading output: " + e.getMessage()); 37 | } finally { 38 | try { 39 | reader.close(); 40 | } catch (IOException e) { 41 | resultHandler.onError("Error closing reader: " + e.getMessage()); 42 | } 43 | } 44 | }); 45 | // 启动线程 46 | outputReaderThread.start(); 47 | } catch (Exception e) { 48 | resultHandler.onError("Error executing command: " + command + "\n" + e.getMessage()); 49 | } 50 | } 51 | 52 | /** 53 | * 处理命令执行结果的回调接口。 54 | */ 55 | public interface ResultHandler { 56 | void onOutput(String output); 57 | void onSuccess(String command); 58 | void onError(String errorMessage); 59 | } 60 | 61 | /** 62 | * 简化的ResultHandler实现。 63 | */ 64 | public static class SimpleResultHandler implements ResultHandler { 65 | @Override 66 | public void onOutput(String output) { 67 | System.out.println("Output: " + output); 68 | } 69 | 70 | @Override 71 | public void onSuccess(String command) { 72 | log.info("Command executed successfully"); 73 | } 74 | 75 | @Override 76 | public void onError(String errorMessage) { 77 | log.error("Error: " + errorMessage); 78 | } 79 | } 80 | 81 | public static void main(String[] args) { 82 | String command1 = "powershell -Command (Get-Content 'C:\\Users\\ankki\\AppData\\Roaming\\Windows agent\\agent.cfg') | ForEach-Object { $_ -replace 'dst_ip=.*', 'dst_ip=172.19.5.45' } | Set-Content 'C:\\Users\\ankki\\AppData\\Roaming\\Windows agent\\agent.cfg'"; 83 | String command2 = "cmd /c cd D:\\Program\\Agent\\5.1.2 && \"Windows Agent.exe\""; 84 | String command3 = "wmic process where name='Windows Agent.exe' delete"; 85 | String command = "ipconfig"; 86 | 87 | // 调用executeCommand方法 88 | executeCommand(command1, null, new SimpleResultHandler()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/Constants.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | public class Constants { 4 | 5 | public static final String CONFIG_JDBC = "src/main/java/jdbc.properties"; 6 | 7 | public static final String CONFIG_COMMON = "src/main/java/common.properties"; 8 | 9 | public static final String CONFIG_APP = "src/main/java/common.properties"; 10 | 11 | /** 12 | * 检查条件:列表大小不为空. 13 | */ 14 | public static final String SIZE_NOT_ZERO = "size_not_null"; 15 | 16 | /** 17 | * 检查条件:字段值是否等于预期. 18 | */ 19 | public static final String FIELD = "field"; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ConstantsUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | 6 | import javax.swing.BorderFactory; 7 | import javax.swing.border.Border; 8 | 9 | /** 10 | * Description: 工具类
11 | * Date: 2014年11月20日 下午2:36:04
12 | * 13 | * @author 刘智 14 | * @version 15 | * @since JDK 1.7 16 | * @see 17 | */ 18 | public class ConstantsUtil { 19 | 20 | public static final String CONFIG_JDBC = "src/main/java/jdbc.properties"; 21 | 22 | public static final String CONFIG_COMMON = "src/main/java/common.properties"; 23 | 24 | /** 25 | * 检查条件:列表大小不为空. 26 | */ 27 | public static final String SIZE_NOT_ZERO = "size_not_null"; 28 | 29 | /** 30 | * 检查条件:字段值是否等于预期. 31 | */ 32 | public static final String FIELD = "field"; 33 | 34 | // 微软雅黑 35 | public static Font BASIC_FONT = new Font("微软雅黑", Font.PLAIN, 12); 36 | public static Font BASIC_FONT2 = new Font("微软雅黑", Font.TYPE1_FONT, 12); 37 | public static Font BASIC_FONT3 = new Font("微软雅黑", Font.PLAIN, 15); 38 | public static Font BASIC_FONT4 = new Font("宋体",Font.BOLD,12); 39 | // 楷体 40 | public static Font DIALOG_FONT = new Font("楷体", Font.PLAIN, 16); 41 | 42 | public static Border GRAY_BORDER = BorderFactory.createLineBorder(Color.GRAY); 43 | public static Border DARKGRAY_BORDER = BorderFactory.createLineBorder(Color.darkGray); 44 | public static Border LIGHT_GRAY_BORDER = BorderFactory.createLineBorder(Color.LIGHT_GRAY); 45 | public static Border BLUE_BORDER = BorderFactory.createLineBorder(Color.BLUE); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/CopyFile.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileOutputStream; 5 | 6 | import org.apache.log4j.Logger; 7 | 8 | /** 9 | * @author 刘智King 10 | * @date 2020年10月19日 下午3:19:58 11 | */ 12 | @SuppressWarnings("resource") 13 | public class CopyFile { 14 | 15 | static Logger log = Logger.getLogger(CopyFile.class); 16 | 17 | public static void copy(String srcPathStr, String desPathStr) { 18 | // 获取源文件的名称 19 | String newFileName = srcPathStr.substring(srcPathStr.lastIndexOf("/") + 1); // 目标文件地址 20 | // log.info("源文件:" + newFileName); 21 | desPathStr = desPathStr + newFileName; // 源文件地址 22 | // log.info("目标文件地址:" + desPathStr); 23 | JSchUtil.mkdirs(desPathStr); 24 | try { 25 | FileInputStream fis = new FileInputStream(srcPathStr);// 创建输入流对象 26 | FileOutputStream fos = new FileOutputStream(desPathStr); // 创建输出流对象 27 | byte datas[] = new byte[1024 * 8];// 创建搬运工具 28 | int len = 0;// 创建长度 29 | while ((len = fis.read(datas)) != -1)// 循环读取数据 30 | { 31 | fos.write(datas, 0, len); 32 | } 33 | fis.close();// 释放资源 34 | fis.close();// 释放资源 35 | } catch (Exception e) { 36 | //e.printStackTrace(); 37 | log.error("",e); 38 | } 39 | } 40 | 41 | public static void main(String[] args) { 42 | String srcPathStr = ""+System.getProperty("user.dir") + "/Logs/log.log"; // 源文件地址 43 | String data = DateUtil.getDateFormat("yyyy-MM-dd"); 44 | String desPathStr = ""+System.getProperty("user.dir") + "/TestOutput/ExtentReport/"+data+"/"; 45 | copy(srcPathStr, desPathStr);// 将E:\\java task\\zhl.txt文件拷贝到E:\\java task\\zhlll 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/DBSSH.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.sql.*; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import com.jcraft.jsch.JSch; 8 | import com.jcraft.jsch.Session; 9 | 10 | public class DBSSH { 11 | 12 | static Logger log = Logger.getLogger(DBSSH.class); 13 | 14 | static int lport = 33101;//本地端口 15 | static String rhost = "rm-wz9f2uq58wflnolke.mysql.rds.aliyuncs.com";//远程MySQL服务器 16 | static int rport = 3306;//远程MySQL服务端口 17 | 18 | public static void go() { 19 | String user = "root";//SSH连接用户名 20 | String password = "\\Jg9.>P#fa8w";//SSH连接密码 21 | String host = "119.23.226.118";//SSH服务器 22 | int port = 22;//SSH访问端口 23 | try { 24 | JSch jsch = new JSch(); 25 | Session session = jsch.getSession(user, host, port); 26 | session.setPassword(password); 27 | session.setConfig("StrictHostKeyChecking", "no"); 28 | session.connect(); 29 | log.info("SSH服务器连接成功,版本信息为:"+session.getServerVersion());//这里打印SSH服务器版本信息 30 | int assinged_port = session.setPortForwardingL(lport, rhost, rport); 31 | log.info("端口映射成功:localhost:" + assinged_port + " -> " + rhost + ":" + rport); 32 | } catch (Exception e) { 33 | //e.printStackTrace(); 34 | log.error("",e); 35 | } 36 | } 37 | 38 | public static void sql() { 39 | Connection conn = null; 40 | ResultSet rs = null; 41 | Statement st = null; 42 | try { 43 | Class.forName("com.mysql.jdbc.Driver"); 44 | conn = DriverManager.getConnection("jdbc:mysql://localhost:33101/travel_test?useUnicode=true&characterEncoding=utf-8&useSSL=false", "user2017", "jUPa5wrlCh"); 45 | st = conn.createStatement(); 46 | String sql = "SELECT * FROM account"; 47 | rs = st.executeQuery(sql); 48 | log.info("开始执行SQL:" + sql); 49 | 50 | // 获取列名 51 | ResultSetMetaData metaData = rs.getMetaData(); 52 | for (int i = 0; i < metaData.getColumnCount(); i++) { 53 | // resultSet数据下标从1开始 54 | String columnName = metaData.getColumnName(i + 1); 55 | int type = metaData.getColumnType(i + 1); 56 | if (Types.INTEGER == type) { 57 | // int 58 | } else if (Types.VARCHAR == type) { 59 | // String 60 | } 61 | log.info(columnName + "\t"); 62 | } 63 | log.info(""); 64 | 65 | // 获取数据 66 | while (rs.next()) { 67 | for (int i = 0; i < metaData.getColumnCount(); i++) { 68 | // resultSet数据下标从1开始 69 | log.info(rs.getString(i + 1) + "\t"); 70 | } 71 | log.info(""); 72 | 73 | } 74 | st.close(); 75 | conn.close(); 76 | } catch (Exception e) { 77 | //e.printStackTrace(); 78 | log.error("",e); 79 | } finally { 80 | //rs.close();st.close();conn.close(); 81 | } 82 | } 83 | 84 | @SuppressWarnings("unused") 85 | private static void getData() throws SQLException, ClassNotFoundException { 86 | 87 | Connection conn = null; 88 | // 获取所有表名 89 | Class.forName("com.mysql.jdbc.Driver"); 90 | conn = DriverManager.getConnection("jdbc:mysql://localhost:33101/travel_test?useUnicode=true&characterEncoding=utf-8&useSSL=false", "user2017", "jUPa5wrlCh"); 91 | Statement statement = conn.createStatement(); 92 | ResultSet resultSet = statement 93 | .executeQuery("SELECT * FROM account"); 94 | // 获取列名 95 | ResultSetMetaData metaData = resultSet.getMetaData(); 96 | for (int i = 0; i < metaData.getColumnCount(); i++) { 97 | // resultSet数据下标从1开始 98 | String columnName = metaData.getColumnName(i + 1); 99 | int type = metaData.getColumnType(i + 1); 100 | if (Types.INTEGER == type) { 101 | // int 102 | } else if (Types.VARCHAR == type) { 103 | // String 104 | } 105 | log.info(columnName + "\t"); 106 | } 107 | log.info(""); 108 | // 获取数据 109 | while (resultSet.next()) { 110 | for (int i = 0; i < metaData.getColumnCount(); i++) { 111 | // resultSet数据下标从1开始 112 | log.info(resultSet.getString(i + 1) + "\t"); 113 | } 114 | log.info(""); 115 | 116 | } 117 | statement.close(); 118 | conn.close(); 119 | } 120 | 121 | public static void main(String[] args) throws SQLException, ClassNotFoundException { 122 | go(); 123 | sql(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ExcelHelper.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.regex.Matcher; 10 | import java.util.regex.Pattern; 11 | 12 | import org.apache.log4j.Logger; 13 | 14 | import jxl.Cell; 15 | import jxl.Sheet; 16 | import jxl.Workbook; 17 | import jxl.read.biff.BiffException; 18 | 19 | public class ExcelHelper { 20 | 21 | static Logger log = Logger.getLogger(ExcelHelper.class); 22 | 23 | private static Workbook WORKBOOK; 24 | 25 | private static final Pattern INDEX_PATTERN = Pattern.compile("^[a-zA-Z]+[0-9]+$"); 26 | 27 | public static void main(String[] args) throws Exception { 28 | String excelPath = ConfigUtil.getProperty("testdata.path", Constants.CONFIG_COMMON); 29 | ExcelHelper.read(excelPath); 30 | List values = ExcelHelper.getCellContentByIndexs(0, "a2", "E8", "E9"); 31 | 32 | values = ExcelHelper.getCellContentByIndexs(0, "A1", "E8", "E9", "D1", "E8", "E9", "D1"); 33 | 34 | 35 | for(String value : values){ 36 | log.info(value); 37 | } 38 | 39 | } 40 | 41 | public static void read(String excelPath) throws BiffException, IOException{ 42 | File file = new File(excelPath); 43 | InputStream in = new FileInputStream(file); 44 | WORKBOOK = Workbook.getWorkbook(in); 45 | } 46 | 47 | public static void close(){ 48 | if(WORKBOOK != null) 49 | WORKBOOK.close(); 50 | WORKBOOK = null; 51 | } 52 | 53 | private static void check(){ 54 | if(WORKBOOK == null) 55 | throw new RuntimeException("文件文空"); 56 | } 57 | 58 | public static List getCellContentByIndexs(int sheetIndex, String... indexs) throws Exception{ 59 | 60 | List cellList = new ArrayList(); 61 | if(indexs == null || indexs.length == 0) 62 | return cellList; 63 | check(); 64 | Sheet sheet = WORKBOOK.getSheet(sheetIndex); 65 | Cell cell; 66 | for(String index : indexs){ 67 | if(checkIndex(index)){ 68 | cell = sheet.getCell(index); 69 | cellList.add(cell.getContents()); 70 | }else{ 71 | throw new Exception("错误的索引值"); 72 | } 73 | } 74 | 75 | return cellList; 76 | } 77 | 78 | private static boolean checkIndex(String index){ 79 | 80 | boolean isOk = false; 81 | if(index == null || "".equals(index)) 82 | return isOk; 83 | Matcher m = INDEX_PATTERN.matcher(index.trim()); 84 | if(m.find()) 85 | isOk = true; 86 | return isOk; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ExcpUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | /** 4 | * @author 刘智King 5 | * @date 2020年10月22日 下午4:49:49 6 | */ 7 | public class ExcpUtil { 8 | // 打印异常堆栈信息 9 | public static String getStackTraceString(Throwable ex) {// (Exception ex) { 10 | StackTraceElement[] traceElements = ex.getStackTrace(); 11 | 12 | StringBuilder traceBuilder = new StringBuilder(); 13 | 14 | if (traceElements != null && traceElements.length > 0) { 15 | for (StackTraceElement traceElement : traceElements) { 16 | traceBuilder.append(traceElement.toString()); 17 | traceBuilder.append("\n"); 18 | } 19 | } 20 | 21 | return traceBuilder.toString(); 22 | } 23 | 24 | // 构造异常堆栈信息 25 | public static String buildErrorMessage(Exception ex) { 26 | 27 | String result; 28 | String stackTrace = getStackTraceString(ex); 29 | String exceptionType = ex.toString(); 30 | String exceptionMessage = ex.getMessage(); 31 | 32 | result = String.format("%s : %s \r\n %s", exceptionType, exceptionMessage, stackTrace); 33 | 34 | return result; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ExecuteSSHToolUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import com.jcraft.jsch.*; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.InputStream; 9 | import java.io.InputStreamReader; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.Properties; 12 | 13 | /** 14 | * 执行Shell工具类 15 | * 16 | */ 17 | public class ExecuteSSHToolUtil { 18 | 19 | private static final Logger log = LoggerFactory.getLogger(ExecuteSSHToolUtil.class); 20 | 21 | /** 未调用初始化方法 错误提示信息 */ 22 | private static final String DONOT_INIT_ERROR_MSG = "please invoke init(...) first!"; 23 | 24 | private Session session; 25 | 26 | private Channel channel; 27 | 28 | private ChannelExec channelExec; 29 | 30 | public ExecuteSSHToolUtil() { 31 | } 32 | 33 | /** 34 | * 获取ExecuteShellUtil类实例对象 35 | * 36 | */ 37 | public static ExecuteSSHToolUtil getInstance() { 38 | return new ExecuteSSHToolUtil(); 39 | } 40 | 41 | /** 42 | * 初始化 43 | * 44 | * @param ip 45 | * 远程Linux地址 46 | * @param port 47 | * 端口 48 | * @param username 49 | * 用户名 50 | * @param password 51 | * 密码 52 | * @throws JSchException 53 | * JSch异常 54 | */ 55 | public void init(String ip, Integer port, String username, String password) throws Exception { 56 | JSch jsch = new JSch(); 57 | try { 58 | session = jsch.getSession(username, ip, port); 59 | session.setPassword(password); 60 | Properties sshConfig = new Properties(); 61 | sshConfig.put("StrictHostKeyChecking", "no"); 62 | session.setConfig(sshConfig); 63 | session.connect(60 * 1000); 64 | log.info("Session connected!"); 65 | // 打开执行shell指令的通道 66 | channel = session.openChannel("exec"); 67 | channelExec = (ChannelExec) channel; 68 | } catch (JSchException e) { 69 | log.error("Failed to connect to SSH session: " + e.getMessage(), e); 70 | throw new Exception("Failed to connect to SSH session: " + e.getMessage(), e); 71 | } 72 | } 73 | 74 | /** 75 | * 执行一条命令 76 | */ 77 | public String execCmd(String command) throws Exception { 78 | if (session == null || channel == null || channelExec == null) { 79 | throw new Exception(DONOT_INIT_ERROR_MSG); 80 | } 81 | log.info("execCmd command - > {}", command); 82 | channelExec.setCommand(command); 83 | channel.setInputStream(null); 84 | channelExec.setErrStream(System.err); 85 | channel.connect(); 86 | StringBuilder sb = new StringBuilder(16); 87 | try (InputStream in = channelExec.getInputStream(); 88 | InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8); 89 | BufferedReader reader = new BufferedReader(isr)) { 90 | String buffer; 91 | while ((buffer = reader.readLine()) != null) { 92 | sb.append("\n").append(buffer); 93 | } 94 | log.info("execCmd result succeed- > {}", sb.toString()); 95 | }catch (Exception e){ 96 | log.info("execCmd result failed- > {}",e.toString()); 97 | }finally { 98 | // 释放资源 99 | close(); 100 | } 101 | return sb.toString(); 102 | } 103 | 104 | /** 105 | * 释放资源 106 | * 107 | * @date 2019/3/15 12:47 108 | */ 109 | private void close() { 110 | if (channelExec != null && channelExec.isConnected()) { 111 | channelExec.disconnect(); 112 | } 113 | if (channel != null && channel.isConnected()) { 114 | channel.disconnect(); 115 | } 116 | if (session != null && session.isConnected()) { 117 | session.disconnect(); 118 | } 119 | log.info("Successfully released resources"); 120 | } 121 | 122 | public static void main(String[] args) throws Exception { 123 | ExecuteSSHToolUtil executeShellUtil = new ExecuteSSHToolUtil(); 124 | executeShellUtil.init("172.19.5.33", 22, "root", "@1fw#2soc$3vpn"); 125 | String result = executeShellUtil.execCmd("df -lh | grep /dev/mapper/sysvg-root | awk '{print $2}'"); 126 | log.info(result); 127 | } 128 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ExecuteShellUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.Closeable; 5 | import java.io.IOException; 6 | import java.io.InputStreamReader; 7 | import java.io.LineNumberReader; 8 | import java.io.PrintWriter; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Vector; 12 | 13 | import org.apache.log4j.Logger; 14 | 15 | import com.jcraft.jsch.ChannelShell; 16 | import com.jcraft.jsch.JSch; 17 | import com.jcraft.jsch.Session; 18 | 19 | /** 20 | * 执行shell命令 21 | */ 22 | public class ExecuteShellUtil { 23 | 24 | static Logger log = Logger.getLogger(ExecuteShellUtil.class); 25 | private Vector stdout; 26 | // 会话session 27 | Session session; 28 | 29 | // 输入IP、端口、用户名和密码,连接远程服务器 30 | public ExecuteShellUtil(final String ipAddress, int port, final String username, final String password) { 31 | try { 32 | JSch jsch = new JSch(); 33 | session = jsch.getSession(username, ipAddress, port); 34 | session.setPassword(password); 35 | session.setConfig("StrictHostKeyChecking", "no"); 36 | session.connect(100000); 37 | if (session.isConnected()) { 38 | log.info("SSH服务器连接成功"); 39 | } 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | public int execute(final String command) { 46 | int returnCode = 0; 47 | ChannelShell channel = null; 48 | PrintWriter printWriter = null; 49 | BufferedReader input = null; 50 | stdout = new Vector(); 51 | try { 52 | channel = (ChannelShell) session.openChannel("shell"); 53 | channel.connect(); 54 | input = new BufferedReader(new InputStreamReader(channel.getInputStream())); 55 | printWriter = new PrintWriter(channel.getOutputStream()); 56 | printWriter.println(command); 57 | printWriter.println("exit"); 58 | printWriter.flush(); 59 | // log.info("The remote command is: "); 60 | String line; 61 | while ((line = input.readLine()) != null) { 62 | stdout.add(line); 63 | log.info(line); 64 | } 65 | } catch (Exception e) { 66 | e.printStackTrace(); 67 | return -1; 68 | } finally { 69 | close(printWriter); 70 | close(input); 71 | if (channel != null) { 72 | channel.disconnect(); 73 | } 74 | } 75 | return returnCode; 76 | } 77 | 78 | // 断开连接 79 | public void close() { 80 | if (session != null) { 81 | session.disconnect(); 82 | } 83 | } 84 | 85 | // 执行命令获取执行结果 86 | public String executeForResult(String command) { 87 | execute(command); 88 | StringBuilder sb = new StringBuilder(); 89 | for (String str : stdout) { 90 | sb.append(str); 91 | } 92 | return sb.toString(); 93 | } 94 | 95 | public static void close(Closeable closeable) { 96 | if (closeable == null) { 97 | return; 98 | } 99 | try { 100 | closeable.close(); 101 | } catch (IOException e) { 102 | e.printStackTrace(); 103 | } 104 | } 105 | 106 | /** 107 | * 运行shell脚本 108 | * @param shell 需要运行的shell脚本 109 | */ 110 | public static void execShell(String shell){ 111 | try { 112 | Runtime.getRuntime().exec(shell); 113 | } catch (Exception e) { 114 | e.printStackTrace(); 115 | } 116 | } 117 | 118 | /** 119 | * 运行shell脚本 new String[]方式 120 | * @param shell 需要运行的shell脚本 121 | */ 122 | public static void execShellBin(String shell){ 123 | try { 124 | Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",shell},null,null); 125 | } catch (Exception e) { 126 | e.printStackTrace(); 127 | } 128 | } 129 | 130 | 131 | /** 132 | * 运行shell并获得结果,注意:如果sh中含有awk,一定要按new String[]{"/bin/sh","-c",shStr}写,才可以获得流 133 | * 134 | * @param shStr 135 | * 需要执行的shell 136 | * @return 137 | */ 138 | public static List runShell(String shStr) { 139 | List strList = new ArrayList(); 140 | try { 141 | Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",shStr},null,null); 142 | InputStreamReader ir = new InputStreamReader(process.getInputStream()); 143 | LineNumberReader input = new LineNumberReader(ir); 144 | String line; 145 | process.waitFor(); 146 | while ((line = input.readLine()) != null){ 147 | strList.add(line); 148 | } 149 | } catch (Exception e) { 150 | e.printStackTrace(); 151 | } 152 | return strList; 153 | } 154 | 155 | public static void main(String[] args) { 156 | ExecuteShellUtil executeShellUtil = new ExecuteShellUtil("172.19.5.60", 2233, "root", "@nKk1^2Oe38&8!~!"); 157 | // // 执行 ls /opt/命令 158 | String result = executeShellUtil.executeForResult("df -h"); 159 | log.info(result); 160 | executeShellUtil.close(); 161 | // runShell(""); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/FreeSSHUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | 8 | import ch.ethz.ssh2.Connection; 9 | import ch.ethz.ssh2.*; 10 | 11 | import org.apache.log4j.Logger; 12 | 13 | /** 14 | * @author 刘智King 15 | * @date 2020年10月16日 下午4:44:10 16 | */ 17 | @SuppressWarnings({"unused"}) 18 | public class FreeSSHUtil { 19 | 20 | static Logger log = Logger.getLogger(FreeSSHUtil.class); 21 | 22 | static String ip; 23 | static int port; 24 | static String username; 25 | static String password; 26 | 27 | public FreeSSHUtil() { 28 | ip = ConfigUtil.getProperty("MI_8_FreeSSHd_IP", Constants.CONFIG_APP); 29 | port = Integer.parseInt(ConfigUtil.getProperty("MI_8_FreeSSHd_Port", Constants.CONFIG_APP)); 30 | username = ConfigUtil.getProperty("MI_8_FreeSSHd_UserName", Constants.CONFIG_APP); 31 | password = ConfigUtil.getProperty("MI_8_FreeSSHd_PassWord", Constants.CONFIG_APP); 32 | } 33 | 34 | public static void cmd(String cmd) { 35 | try { 36 | Connection conn = new Connection(ip); 37 | conn.connect(); 38 | log.info("开始Linux连接Windows:" + ip + " " + username + " " + password); 39 | log.info("ssh " + username + "@" + ip); 40 | conn.authenticateWithPassword(username, password); 41 | Session sess = conn.openSession(); 42 | log.info("连接成功,开始执行cmd命令"); 43 | log.info("cmd /c " + cmd); 44 | sess.execCommand("cmd /c " + cmd); 45 | InputStream stdout = new StreamGobbler(sess.getStdout()); 46 | BufferedReader br = new BufferedReader(new InputStreamReader(stdout, "utf-8")); 47 | // while (true) { 48 | // String line = br.readLine(); 49 | // if (line == null) 50 | // break; 51 | // log.info(line); 52 | // } 53 | sess.close(); 54 | conn.close(); 55 | } catch (IOException e) { 56 | //e.printStackTrace(); 57 | log.error("",e); 58 | } 59 | } 60 | 61 | public static void cmd(String ip, String username, String password, String cmd) { 62 | try { 63 | // 建立连接 64 | Connection conn = new Connection(ip); 65 | conn.connect(); 66 | // 利用用户名和密码进行授权 67 | log.info("开始Linux连接Windows:" + ip + " " + username + " " + password); 68 | log.info("ssh " + username + "@" + ip); 69 | conn.authenticateWithPassword(username, password); 70 | // 打开会话 71 | Session sess = conn.openSession(); 72 | log.info("连接成功,开始执行cmd命令"); 73 | // 执行命令 74 | log.info("cmd /c " + cmd); 75 | sess.execCommand("cmd /c " + cmd); 76 | InputStream stdout = new StreamGobbler(sess.getStdout()); 77 | BufferedReader br = new BufferedReader(new InputStreamReader(stdout, "utf-8")); 78 | // while (true) { 79 | // String line = br.readLine(); 80 | // if (line == null) 81 | // break; 82 | // log.info(line); 83 | // } 84 | sess.close(); 85 | conn.close(); 86 | } catch (IOException e) { 87 | //e.printStackTrace(); 88 | log.error("",e); 89 | } 90 | } 91 | 92 | public static void main(String[] args) { 93 | cmd("172.18.1.118", "king", "111111", "git clone http://172.19.5.222:8099/Test/Ankki.Web.UI.Automation.Test.git"); 94 | // cmd("10.18.22.32", "King-liu", "111111", "taskkill /f /IM node.exe"); 95 | // cmd("10.18.22.32", "King-liu", "111111", 96 | // "node C:/Users/King-liu/AppData/Local/Programs/Appium/resources/app/node_modules/appium/build/lib/main.js --address 10.18.22.32 --port 4723>D:/appium.txt"); 97 | // cmd("10.18.22.65", "Administrator", "111111", "node 98 | // C:/Users/Administrator/AppData/Local/Programs/Appium/resources/app/node_modules/appium/build/lib/main.js 99 | // --address 10.18.22.65 --port 4723"); 100 | // cmd("10.18.22.65", "Administrator", "111111", "cd c: &&rd 123.txt"); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/HttpRequestUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import io.restassured.RestAssured; 4 | import io.restassured.config.SSLConfig; 5 | import io.restassured.response.Response; 6 | 7 | import java.util.Map; 8 | 9 | import org.apache.log4j.Logger; 10 | 11 | import static io.restassured.RestAssured.given; 12 | 13 | public class HttpRequestUtil { 14 | static Logger log = Logger.getLogger(HttpRequestUtil.class); 15 | 16 | /** 17 | * 指定API接口URL,POST请求参数,获取Cookie 18 | * @param ApiUrl 19 | * @param Param 20 | * @return 21 | * @throws Exception 22 | */ 23 | public static Map GetPostCookie(String ApiUrl, String Param) throws Exception{ 24 | 25 | Response response = given() 26 | .config((RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))) 27 | .contentType("application/json") 28 | .request() 29 | .body(Param) 30 | .when() 31 | .post(ApiUrl); 32 | 33 | response.print(); 34 | Map allCookies=response.getCookies(); 35 | log.info("allCookies"+allCookies); 36 | 37 | return allCookies; 38 | } 39 | 40 | /** 41 | * 指定API接口URL,POST请求参数,获取Json结果 42 | * @param ApiUrl 43 | * @param Param 44 | * @param Cookie 45 | * @return 46 | * @throws Exception 47 | */ 48 | public static String GetJsonResult(String ApiUrl, String Param, Map Cookie) throws Exception{ 49 | 50 | Response response = given() 51 | .config((RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))) 52 | .contentType("application/json") 53 | .log().all() 54 | .request() 55 | .body(Param) 56 | .cookies(Cookie) 57 | .when() 58 | .post(ApiUrl); 59 | 60 | // 打印出 response 的body 61 | // response1.print(); 62 | String result = response.asString(); 63 | log.info("返回的值Json:"+result); 64 | 65 | return result; 66 | } 67 | 68 | /** 69 | * 指定API接口URL,POST请求参数,获取int类型值 70 | * @param ApiUrl 71 | * @param Param 72 | * @param Cookie 73 | * @return 74 | * @throws Exception 75 | */ 76 | public static int GetJsonIntValue(String ApiUrl, String Param, Map Cookie, String Value) throws Exception{ 77 | 78 | Response response = given() 79 | .config((RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))) 80 | .contentType("application/json") 81 | .log().all() 82 | .request() 83 | .body(Param) 84 | .cookies(Cookie) 85 | .when() 86 | .post(ApiUrl); 87 | 88 | 89 | int Value1 = response.jsonPath().getInt(Value); 90 | log.info("Value:"+Value1); 91 | 92 | return Value1; 93 | } 94 | 95 | /** 96 | * 指定API接口URL,POST请求参数,获取String类型值 97 | * @param ApiUrl 98 | * @param Param 99 | * @param Cookie 100 | * @return 101 | * @throws Exception 102 | */ 103 | public static String GetJsonStringValue(String ApiUrl, String Param, Map Cookie, String Value) throws Exception{ 104 | 105 | Response response = given() 106 | .config((RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))) 107 | .contentType("application/json") 108 | .log().all() 109 | .request() 110 | .body(Param) 111 | .cookies(Cookie) 112 | .when() 113 | .post(ApiUrl); 114 | 115 | String Value1 = response.jsonPath().get(Value); 116 | log.info("Value:"+Value1); 117 | 118 | return Value1; 119 | } 120 | 121 | /** 122 | * 指定API接口URL,POST请求参数,获取状态码 123 | * @param ApiUrl 124 | * @param Param 125 | * @param Cookie 126 | * @return 127 | * @throws Exception 128 | */ 129 | public static int GetStatusCode(String ApiUrl, String Param, Map Cookie) throws Exception{ 130 | 131 | Response response = given() 132 | .config((RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))) 133 | .contentType("application/json") 134 | .log().all() 135 | .request() 136 | .body(Param) 137 | .cookies(Cookie) 138 | .when() 139 | .post(ApiUrl); 140 | 141 | // 打印出 response 的statusCode 142 | int statusCode = response.getStatusCode(); 143 | log.info("statusCode:" + statusCode); 144 | 145 | return statusCode; 146 | } 147 | 148 | /** 149 | * 指定API接口URL,发送POST请求 150 | * @param ApiUrl 151 | * @param Param 152 | * @return 153 | * @return 154 | * @throws Exception 155 | */ 156 | public static void SendPost(String ApiUrl, String Param) throws Exception{ 157 | 158 | Response response = given() 159 | .config((RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))) 160 | .contentType("application/json") 161 | .request() 162 | .body(Param) 163 | .when() 164 | .post(ApiUrl); 165 | 166 | // 打印出 response 的statusCode 167 | int statusCode = response.getStatusCode(); 168 | log.info("『正常测试』开始执行: " + "<接口请求成功,状态码为:"+statusCode+">"); 169 | // log.info("statusCode:" + statusCode); 170 | } 171 | 172 | /** 173 | * 指定API接口URL,发送PUT请求 174 | * @param ApiUrl 175 | * @param Param 176 | * @return 177 | * @return 178 | * @throws Exception 179 | */ 180 | public static void SendPut(String ApiUrl, String Param) throws Exception{ 181 | Response response = given() 182 | .config((RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation()))) 183 | .contentType("application/json") 184 | .log().all() 185 | .request() 186 | .body(Param) 187 | .when() 188 | .put(ApiUrl); 189 | 190 | log.info("response:" + response.asString()); 191 | } 192 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/MapUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | import java.util.Set; 6 | 7 | import org.apache.log4j.Logger; 8 | 9 | import com.alibaba.fastjson.JSONObject; 10 | 11 | /** 12 | * @author 刘智King 13 | * @date 2020年9月17日 下午1:29:30 14 | */ 15 | public class MapUtil { 16 | static Logger log = Logger.getLogger(MapUtil.class); 17 | 18 | public static void main(String[] args) { 19 | 20 | Map map1 = new LinkedHashMap(); 21 | map1.put("", ""); 22 | map1.put("1.强制等待3秒", "1.png"); 23 | map1.put("2.强制等待3秒", "2.png"); 24 | map1.put("3.强制等待3秒", "3.png"); 25 | log.info(map1); 26 | 27 | Map map2 = new LinkedHashMap(); 28 | map2.put("", ""); 29 | map2.put("11", "11.png"); 30 | map2.put("22", "22.png"); 31 | map2.put("33", "33.png"); 32 | log.info(map2); 33 | 34 | // Map转String 35 | String str1 = getMapToString(map1); 36 | String str2 = getMapToString(map2); 37 | log.info(str1); 38 | log.info(str2); 39 | 40 | Map map3 = new LinkedHashMap(); 41 | map3.put("case1", str1); 42 | map3.put("case2", str2); 43 | log.info(map3); 44 | log.info(map3.get("case1")); 45 | log.info(map3.get("case2")); 46 | for (Object cased : map3.keySet()) { 47 | log.info(cased + " " + map3.get(cased)); 48 | } 49 | 50 | log.info(map3.get("case1").toString()); 51 | Map map4 = getStringToMap(map3.get("case1").toString()); 52 | for (Object cased : map4.keySet()) { 53 | log.info(cased + " " + map4.get(cased)); 54 | } 55 | // Map转String 56 | String str3 = getMapToString(map4); 57 | log.info(str3); 58 | 59 | // String转map 60 | Map map5 = getStringToMap(str3); 61 | log.info(map5); 62 | for (Object cased : map5.keySet()) { 63 | log.info(cased + " " + map5.get(cased)); 64 | } 65 | 66 | // String转map 67 | Map map6 = getStringToMap("查询数据库获=发送1=1, 查询数据库获=发送2=2, 查询数据库获=发送3=3"); 68 | log.info(map6); 69 | for (Object cased : map6.keySet()) { 70 | log.info(cased + " " + map6.get(cased)); 71 | } 72 | 73 | String str = "查询数据库获=发送=发发发发=1"; 74 | String key = str.substring(0, str.lastIndexOf("=")); 75 | String value = str.substring(str.lastIndexOf("=") + 1, str.length()); 76 | log.info(key + " " + value); 77 | 78 | Map map7 = getStringToMap("查询数据库获=发送1=, 查询数据库获=发送2=, 查询数据库获=发送3="); 79 | log.info(getMapToJson(map7)); 80 | } 81 | 82 | /** 83 | * 84 | * Map转String 85 | * 86 | * @param map 87 | * @return 88 | */ 89 | public static String getMapToString(Map map) { 90 | Set keySet = map.keySet(); 91 | // 将set集合转换为数组 92 | String[] keyArray = keySet.toArray(new String[keySet.size()]); 93 | // 给数组排序(升序) 94 | // Arrays.sort(keyArray); 95 | // 因为String拼接效率会很低的,所以转用StringBuilder 96 | StringBuilder sb = new StringBuilder(); 97 | for (int i = 0; i < keyArray.length; i++) { 98 | // 参数值为空,则不参与签名 这个方法trim()是去空格 99 | if ((String.valueOf(map.get(keyArray[i]))).trim().length() >= 0) { 100 | sb.append(keyArray[i]).append("=").append(String.valueOf(map.get(keyArray[i])).trim()); 101 | } 102 | if (i != keyArray.length - 1) { 103 | sb.append(", "); 104 | } 105 | } 106 | return sb.toString(); 107 | } 108 | 109 | /** 110 | * 111 | * String转map 112 | * 113 | * @param str 114 | * @return 115 | */ 116 | public static Map getStringToMap(String str) { 117 | // 根据逗号截取字符串数组 118 | String[] str1 = str.split(", "); 119 | // 创建Map对象 120 | Map map = new LinkedHashMap(); 121 | // 循环加入map集合 122 | for (int i = 0; i < str1.length; i++) { 123 | // 根据":"截取字符串数组 124 | // String[] str2 = str1[i].split("="); 125 | // log.info(str2[0]); 126 | //// log.info(str2[0]); 127 | //// log.info(str2[1]); 128 | // //str2[0]为KEY,str2[1]为值 129 | // if(str2.length==0){ 130 | // map.put("",""); 131 | // }else if(str2.length==1){ 132 | // map.put(str2[0],""); 133 | // }else{ 134 | // map.put(str2[0],str2[1]); 135 | // } 136 | String key = str1[i].substring(0, str1[i].lastIndexOf("=")); 137 | String value = str1[i].substring(str1[i].lastIndexOf("=") + 1, str1[i].length()); 138 | map.put(key, value); 139 | } 140 | return map; 141 | } 142 | 143 | public static Map getStringToMap1(String str) { 144 | // 根据逗号截取字符串数组 145 | String[] str1 = str.split(", "); 146 | // 创建Map对象 147 | Map map = new LinkedHashMap(); 148 | // 循环加入map集合 149 | for (int i = 0; i < str1.length; i++) { 150 | // 根据":"截取字符串数组 151 | // String[] str2 = str1[i].split("="); 152 | // log.info(str2[0]); 153 | //// log.info(str2[0]); 154 | //// log.info(str2[1]); 155 | // //str2[0]为KEY,str2[1]为值 156 | // if(str2.length==0){ 157 | // map.put("",""); 158 | // }else if(str2.length==1){ 159 | // map.put(str2[0],""); 160 | // }else{ 161 | // map.put(str2[0],str2[1]); 162 | // } 163 | String key = str1[i].substring(0, str1[i].indexOf("=")); 164 | String value = str1[i].substring(str1[i].indexOf("=") + 1, str1[i].length()); 165 | map.put(key, value); 166 | } 167 | return map; 168 | } 169 | 170 | public static JSONObject getMapToJson(Map map) { 171 | // Map map = new HashMap(); 172 | // map.put("a", "a"); 173 | // map.put("b", "123"); 174 | // JSONObject json = new JSONObject(Headers); 175 | // json.forEach((key,value)->{ 176 | // log.info(key+" : "+value); 177 | // Headers.put(key, value); 178 | // }); 179 | JSONObject json = new JSONObject(map); 180 | return json; 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/MongoDBUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import org.apache.log4j.Logger; 4 | import org.bson.Document; 5 | import com.mongodb.client.*; 6 | import com.mongodb.ConnectionString; 7 | import com.mongodb.client.MongoClient; 8 | import com.mongodb.MongoClientSettings; 9 | 10 | import java.util.ArrayList; 11 | import java.util.LinkedHashMap; 12 | import java.util.List; 13 | 14 | public class MongoDBUtil { 15 | static Logger log = Logger.getLogger(MongoDBUtil.class); 16 | 17 | private final MongoClient mongoClient; 18 | private final MongoDatabase database; 19 | 20 | public MongoDBUtil(String host, String port, String username, String password, String databaseName) { 21 | String connectionString = "mongodb://" + username + ":" + password + "@" + host + ":" + port + "/" + databaseName + "?authSource=admin"; 22 | ConnectionString connString = new ConnectionString(connectionString); 23 | MongoClientSettings settings = MongoClientSettings.builder() 24 | .applyConnectionString(connString) 25 | .build(); 26 | 27 | this.mongoClient = MongoClients.create(settings); 28 | // 创建数据库,如果数据库不存在则会创建,如果存在,则会切换到指定数据库 29 | database = mongoClient.getDatabase(databaseName); 30 | } 31 | 32 | // 创建集合,如果集合不存在则创建 33 | public void createCollection(String collectionName) { 34 | List collectionNames = new ArrayList<>(); 35 | database.listCollectionNames().into(collectionNames); 36 | if (!collectionNames.contains(collectionName)) { 37 | database.createCollection(collectionName); 38 | log.info("Collection created: " + collectionName); 39 | } else { 40 | log.info("Collection already exists: " + collectionName); 41 | } 42 | } 43 | 44 | // 执行增删改查操作的方法 45 | public List executeOperation(String operationType, String collectionName, Document filterDoc, Document updateDoc) { 46 | MongoCollection collection = database.getCollection(collectionName); 47 | switch (operationType) { 48 | case "CREATE": 49 | collection.insertOne(filterDoc); // 这里filterDoc作为要插入的文档 50 | return null; 51 | case "DELETE": 52 | collection.deleteOne(filterDoc).getDeletedCount(); 53 | return null; 54 | case "UPDATE": 55 | collection.updateOne(filterDoc, new Document("$set", updateDoc)); 56 | return null; 57 | case "SELECT": 58 | // 查询所有 59 | FindIterable foundDocuments; 60 | List results = new ArrayList<>(); 61 | if (filterDoc == null || filterDoc.isEmpty()) { 62 | foundDocuments = collection.find(); 63 | } else { 64 | foundDocuments = collection.find(filterDoc); 65 | } 66 | for (Document doc : foundDocuments) { 67 | // log.info(doc.toJson()); 68 | results.add(doc.toJson()); 69 | } 70 | return results; // 返回查询结果 71 | default: 72 | throw new IllegalArgumentException("Unsupported operation type."); 73 | } 74 | } 75 | 76 | // 关闭连接 77 | public void close() { 78 | mongoClient.close(); 79 | } 80 | 81 | public enum OperationType { 82 | CREATE, DELETE, UPDATE, SELECT 83 | } 84 | 85 | public static void main(String[] args) { 86 | MongoDBUtil mongoDBUtil = new MongoDBUtil("172.19.1.233", "27017", "root", "Ceshi123", "test"); 87 | 88 | // // 创建集合 89 | // mongoDBUtil.createCollection("test"); 90 | // 91 | // // 插入数据 92 | // Document toInsert = new Document("name", "MongoDB") 93 | // .append("type", "database") 94 | // .append("count", 1) 95 | // .append("info", new Document("x", 203).append("y", 102)); 96 | // Document doc = new Document("title", "MongoDB") 97 | // .append("description", "Musql is a RDBMS") 98 | // .append("by", "sql练习") 99 | // .append("url", "http://www.runoob.com") 100 | // .append("tages", Arrays.asList("mongodb", "database", "NoSQL")) 101 | // .append("likes", 100); 102 | // mongoDBUtil.executeOperation(OperationType.CREATE, "test", toInsert, null); 103 | // 104 | // // 删除数据 105 | // Document deleteFilter = new Document("name", "MongoDB"); 106 | // mongoDBUtil.executeOperation(OperationType.DELETE, "test", deleteFilter, null); 107 | // 108 | // // 更新数据 109 | // Document updateFilter = new Document("name", "MongoDB"); 110 | // Document updateDoc = new Document("count", 2); 111 | // mongoDBUtil.executeOperation(OperationType.UPDATE, "yourCollectionName", updateFilter, updateDoc); 112 | 113 | // 查询数据 114 | Document findFilter = new Document("name", "张三"); 115 | List st = mongoDBUtil.executeOperation("SELECT", "tb4", null, null); 116 | log.info(st); 117 | // 关闭连接 118 | mongoDBUtil.close(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/MongoDBUtil1.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import com.mongodb.ConnectionString; 4 | import com.mongodb.MongoClientSettings; 5 | import com.mongodb.MongoCommandException; 6 | import com.mongodb.client.*; 7 | import com.mongodb.client.model.Filters; 8 | import com.mongodb.client.model.Updates; 9 | import com.mongodb.client.result.DeleteResult; 10 | import com.mongodb.client.result.UpdateResult; 11 | import org.bson.Document; 12 | import org.bson.conversions.Bson; 13 | import java.util.ArrayList; 14 | 15 | public class MongoDBUtil1 { 16 | // 连接信息 17 | private static final String URI = "mongodb://localhost:27017"; 18 | private static final String DATABASE = "testdb"; 19 | private static final String COLLECTION = "users"; 20 | 21 | private static MongoClient client; 22 | private static MongoCollection collection; 23 | 24 | public MongoDBUtil1(String host, int port, String username, String password, String databaseName) { 25 | String connectionString = "mongodb://" + username + ":" + password + "@" + host + ":" + port + "/" + databaseName + "?authSource=admin"; 26 | ConnectionString connString = new ConnectionString(connectionString); 27 | MongoClientSettings settings = MongoClientSettings.builder() 28 | .applyConnectionString(connString) 29 | .build(); 30 | 31 | client = MongoClients.create(settings); 32 | // 创建数据库,如果数据库不存在则会创建,如果存在,则会切换到指定数据库 33 | MongoDatabase database = client.getDatabase(databaseName); 34 | 35 | // 判断集合是否存在 36 | if (collectionExists(database)) { 37 | try { 38 | database.createCollection(COLLECTION); 39 | System.out.println("集合创建成功: " + COLLECTION); 40 | } catch (MongoCommandException e) { 41 | if (e.getErrorCode() == 48) { // 错误码48表示集合已存在 42 | System.out.println("集合已存在,直接使用: " + COLLECTION); 43 | } else { 44 | throw e; 45 | } 46 | } 47 | } 48 | collection = database.getCollection(COLLECTION); 49 | } 50 | 51 | public static void main(String[] args) { 52 | try { 53 | // 初始化连接并验证/创建集合 54 | initialize(); 55 | 56 | // 插入文档 57 | insertUser("Alice", "alice@example.com"); 58 | insertUser("Bob", "bob@example.com"); 59 | 60 | // 查询所有文档 61 | findAllUsers(); 62 | 63 | // 更新文档 64 | updateUserEmail("Alice", "new.alice@example.com"); 65 | 66 | // 删除文档 67 | deleteUser("Bob"); 68 | 69 | // 再次查询验证结果 70 | findAllUsers(); 71 | } finally { 72 | if (client != null) { 73 | client.close(); 74 | } 75 | } 76 | } 77 | 78 | // 初始化数据库连接并确保集合存在 79 | private static void initialize() { 80 | client = MongoClients.create(URI); 81 | MongoDatabase database = client.getDatabase(DATABASE); 82 | 83 | // 判断集合是否存在 84 | if (collectionExists(database)) { 85 | try { 86 | database.createCollection(COLLECTION); 87 | System.out.println("集合创建成功: " + COLLECTION); 88 | } catch (MongoCommandException e) { 89 | if (e.getErrorCode() == 48) { // 错误码48表示集合已存在 90 | System.out.println("集合已存在,直接使用: " + COLLECTION); 91 | } else { 92 | throw e; 93 | } 94 | } 95 | } 96 | collection = database.getCollection(COLLECTION); 97 | } 98 | 99 | // 检查集合是否存在 100 | private static boolean collectionExists(MongoDatabase database) { 101 | return !database.listCollectionNames() 102 | .into(new ArrayList<>()) 103 | .contains(COLLECTION); 104 | } 105 | 106 | // 插入文档 107 | public static void insertUser(String name, String email) { 108 | Document doc = new Document() 109 | .append("name", name) 110 | .append("email", email); 111 | collection.insertOne(doc); 112 | System.out.println("插入成功: " + name); 113 | } 114 | 115 | // 查询所有文档 116 | public static void findAllUsers() { 117 | FindIterable result = collection.find(); 118 | System.out.println("\n当前用户列表:"); 119 | for (Document doc : result) { 120 | System.out.printf( 121 | "ID: %s | 姓名: %-10s | 邮箱: %s%n", 122 | doc.getObjectId("_id"), 123 | doc.getString("name"), 124 | doc.getString("email") 125 | ); 126 | } 127 | } 128 | 129 | // 更新文档 130 | public static void updateUserEmail(String name, String newEmail) { 131 | Bson filter = Filters.eq("name", name); 132 | Bson update = Updates.set("email", newEmail); 133 | UpdateResult result = collection.updateOne(filter, update); 134 | 135 | if (result.getModifiedCount() > 0) { 136 | System.out.println("更新成功: " + name); 137 | } else { 138 | System.out.println("未找到用户: " + name); 139 | } 140 | } 141 | 142 | // 删除文档 143 | public static void deleteUser(String name) { 144 | DeleteResult result = collection.deleteOne(Filters.eq("name", name)); 145 | if (result.getDeletedCount() > 0) { 146 | System.out.println("删除成功: " + name); 147 | } else { 148 | System.out.println("未找到用户: " + name); 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/MouseUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.awt.Robot; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import com.sakura.base.TestStep; 8 | import com.sakura.service.RunUnitService; 9 | 10 | public class MouseUtil { 11 | Logger log = Logger.getLogger(MouseUtil.class); 12 | 13 | private Robot robot; 14 | 15 | /** 16 | *
模拟移动鼠标到指定位置x,y
17 | * https://blog.csdn.net/qq_46029070/article/details/126014028 18 | * @param step 19 | * @throws Exception 20 | */ 21 | public void mouseMove(TestStep step) throws Exception { 22 | log.info("『正常测试』开始执行: " + "<" + step.getId() + "." + step.getName() + ">"); 23 | RunUnitService.Step.put("name", "" + step.getId() + "." + step.getName() + ""); 24 | 25 | int x = Integer.valueOf(step.getDetails().get("x")); 26 | int y = Integer.valueOf(step.getDetails().get("y")); 27 | robot = new Robot(); 28 | robot.mouseMove(x, y); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ObsRemoteUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import javax.websocket.*; 4 | import java.io.IOException; 5 | import java.net.URI; 6 | import java.util.concurrent.CountDownLatch; 7 | 8 | public class ObsRemoteUtil { 9 | 10 | private static final String OBS_WEBSOCKET_URL = "ws://172.19.5.231:4455"; 11 | private static final String OBS_WEBSOCKET_PASSWORD = "your_password"; 12 | private static final String SCENE_NAME = "11"; 13 | 14 | public static void main(String[] args) throws IOException, InterruptedException, DeploymentException { 15 | // 创建WebSocket容器 16 | WebSocketContainer container = ContainerProvider.getWebSocketContainer(); 17 | 18 | // 创建连接 19 | Session session = container.connectToServer(new ObsWebSocketEndpoint(), URI.create(OBS_WEBSOCKET_URL)); 20 | 21 | // 认证 22 | authenticate(session, OBS_WEBSOCKET_PASSWORD); 23 | 24 | // 切换场景 25 | switchScene(session, SCENE_NAME); 26 | 27 | // 开始录制 28 | startRecording(session); 29 | 30 | // 等待60秒 31 | Thread.sleep(60 * 1000); 32 | 33 | // 停止录制 34 | stopRecording(session); 35 | 36 | // 关闭连接 37 | session.close(); 38 | } 39 | 40 | private static void authenticate(Session session, String password) throws IOException { 41 | session.getBasicRemote().sendText("{\"request-type\": \"GetAuthRequired\"}"); 42 | session.getBasicRemote().sendText("{\"request-type\": \"Authenticate\", \"auth-token\": \"" + password + "\"}"); 43 | } 44 | 45 | private static void switchScene(Session session, String sceneName) throws IOException { 46 | session.getBasicRemote().sendText("{\"request-type\": \"SetCurrentProgramScene\", \"scene-name\": \"" + sceneName + "\"}"); 47 | } 48 | 49 | private static void startRecording(Session session) throws IOException { 50 | session.getBasicRemote().sendText("{\"request-type\": \"StartRecording\"}"); 51 | } 52 | 53 | private static void stopRecording(Session session) throws IOException { 54 | session.getBasicRemote().sendText("{\"request-type\": \"StopRecording\"}"); 55 | } 56 | 57 | // WebSocket端点 58 | private static class ObsWebSocketEndpoint { 59 | 60 | private Session session; 61 | private CountDownLatch latch = new CountDownLatch(1); 62 | 63 | @OnOpen 64 | public void onOpen(Session session, EndpointConfig config) { 65 | this.session = session; 66 | System.out.println("WebSocket connection opened."); 67 | } 68 | 69 | @OnClose 70 | public void onClose(Session session) { 71 | System.out.println("WebSocket connection closed."); 72 | } 73 | 74 | @OnMessage 75 | public void onMessage(String message) { 76 | System.out.println("Received message: " + message); 77 | latch.countDown(); // 解锁,用于同步 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/OrderedProperties.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.util.Collections; 4 | import java.util.Enumeration; 5 | import java.util.LinkedHashSet; 6 | import java.util.Properties; 7 | import java.util.Set; 8 | 9 | /** 10 | * @author 刘智King 11 | * @date 2020年9月7日 下午3:29:57 12 | */ 13 | 14 | public class OrderedProperties extends Properties { 15 | private static final long serialVersionUID = -4627607243846121965L; 16 | private final LinkedHashSet keys = new LinkedHashSet(); 17 | 18 | public Enumeration keys() { 19 | return Collections. enumeration(keys); 20 | } 21 | 22 | public Object put(Object key, Object value) { 23 | keys.add(key); 24 | return super.put(key, value); 25 | } 26 | 27 | public synchronized Object remove(Object key) { 28 | keys.remove(key); 29 | return super.remove(key); 30 | } 31 | 32 | public Set keySet() { 33 | return keys; 34 | } 35 | 36 | public Set stringPropertyNames() { 37 | Set set = new LinkedHashSet(); 38 | for (Object key : this.keys) { 39 | set.add((String) key); 40 | } 41 | return set; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/PingUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.nio.charset.Charset; 8 | 9 | import org.apache.log4j.Logger; 10 | 11 | /** 12 | * @Author: 刘智 13 | * @Date:2022年9月29日 18:29:34 14 | */ 15 | public class PingUtil { 16 | static Logger log = Logger.getLogger(PingUtil.class); 17 | 18 | /**ping ipaddress 完整返回信息*/ 19 | public static String executeLinuxCmd(String ipAddress, int pingTimes, int timeOut) { 20 | Runtime run = Runtime.getRuntime(); 21 | String pingCommand; 22 | try { 23 | String osName = System.getProperty("os.name"); 24 | if(osName.contains("Windows")){ 25 | pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut; 26 | }else{ 27 | pingCommand = "ping " + " -c " + "4" + " -w " + "2 " + ipAddress; 28 | } 29 | Process process = run.exec(pingCommand); 30 | InputStream in = process.getInputStream(); 31 | BufferedReader bs = new BufferedReader(new InputStreamReader(in, Charset.forName("GBK"))); 32 | StringBuffer out = new StringBuffer(); 33 | String content = null; 34 | while ((content = bs.readLine()) != null) { 35 | out.append(content + "\n"); 36 | } 37 | in.close(); 38 | process.destroy(); 39 | return out.toString(); 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | } 43 | return null; 44 | } 45 | 46 | /**ping ipaddress 完整返回true在线 false离线*/ 47 | public static boolean ping(String ipAddress, int pingTimes, int timeOut) { 48 | BufferedReader in = null; 49 | String pingCommand; 50 | Runtime r = Runtime.getRuntime(); 51 | String osName = System.getProperty("os.name"); 52 | if(osName.contains("Windows")){ 53 | pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut; 54 | }else{ 55 | pingCommand = "ping " + " -c " + "4" + " -w " + "2 " + ipAddress; 56 | } 57 | try { 58 | Process p = r.exec(pingCommand); 59 | if (p == null) { 60 | return false; 61 | } 62 | in = new BufferedReader(new InputStreamReader(p.getInputStream())); 63 | int connectedCount = 0; 64 | String line; 65 | while ((line = in.readLine()) != null) { 66 | connectedCount += getCheckResult(line,osName); 67 | } 68 | return connectedCount >= 2 ? true : false; 69 | } catch (Exception ex) { 70 | ex.printStackTrace(); //出现异常则返回假 71 | return false; 72 | } finally { 73 | try { 74 | in.close(); 75 | } catch (IOException e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | } 80 | private static int getCheckResult(String line,String osName) { 81 | if(osName.contains("Windows")){ 82 | if(line.contains("TTL=")){ 83 | return 1; 84 | } 85 | }else{ 86 | if(line.contains("ttl=")){ 87 | return 1; 88 | } 89 | } 90 | return 0; 91 | } 92 | 93 | /** 94 | * Ping IP 95 | * 96 | * @return Inet4Address> 97 | */ 98 | public static boolean ping(String ip){ 99 | Runtime runtime = Runtime.getRuntime(); // 获取当前程序的运行进对象 100 | Process process = null; // 声明处理类对象 101 | String line = null; // 返回行信息 102 | InputStream is = null; // 输入流 103 | InputStreamReader isr = null; // 字节流 104 | BufferedReader br = null; 105 | boolean res = false;// 结果 106 | try { 107 | process = runtime.exec("ping " + ip); // PING 108 | 109 | is = process.getInputStream(); // 实例化输入流 110 | isr = new InputStreamReader(is);// 把输入流转换成字节流 111 | br = new BufferedReader(isr);// 从字节中读取文本 112 | while ((line = br.readLine()) != null) { 113 | if (line.contains("TTL") || line.contains("ttl")) { 114 | res = true; 115 | break; 116 | } 117 | } 118 | is.close(); 119 | isr.close(); 120 | br.close(); 121 | if (res) { 122 | // System.out.println("ping 通 ..."); 123 | return true; 124 | 125 | } else { 126 | // System.out.println("ping 不通..."); 127 | return false; 128 | } 129 | } catch (IOException e) { 130 | System.out.println(e); 131 | runtime.exit(1); 132 | } 133 | return false; 134 | } 135 | 136 | public static void main(String args[]) { 137 | // ping("172.19.5.10"); 138 | 139 | String ping = executeLinuxCmd("172.19.5.10", 2, 1); 140 | log.info(ping); 141 | 142 | boolean ping1 = ping("172.19.5.10", 2, 1); 143 | log.info("IP地址:" + "172.19.5.10" + (ping1 ? "在线" : "下线")); 144 | } 145 | } -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ScreenCaptureExample.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import org.bytedeco.ffmpeg.global.avcodec; 4 | import org.bytedeco.javacv.FFmpegFrameGrabber; 5 | import org.bytedeco.javacv.FFmpegFrameRecorder; 6 | import org.bytedeco.javacv.Frame; 7 | import org.bytedeco.javacv.FrameGrabber; 8 | 9 | import java.awt.*; 10 | import java.io.IOException; 11 | import java.util.concurrent.CountDownLatch; 12 | 13 | public class ScreenCaptureExample { 14 | 15 | private static volatile boolean capturing = false; 16 | private static final CountDownLatch capturingLatch = new CountDownLatch(1); 17 | 18 | public static void main(String[] args) { 19 | try { 20 | startCapture(); 21 | } catch (IOException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | public static void startCapture() throws IOException { 27 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 28 | 29 | FFmpegFrameGrabber grabber = createFFmpegFrameGrabber(screenSize); 30 | FFmpegFrameRecorder recorder = createFFmpegFrameRecorder(grabber, screenSize); 31 | 32 | try { 33 | grabber.start(); 34 | recorder.start(); 35 | 36 | capturing = true; 37 | System.out.println("开始捕获屏幕..."); 38 | Thread captureThread = new Thread(() -> { 39 | try { 40 | captureFrames(grabber, recorder); 41 | } catch (FFmpegFrameRecorder.Exception | FFmpegFrameGrabber.Exception e) { 42 | throw new RuntimeException(e); 43 | } 44 | }); 45 | captureThread.start(); 46 | 47 | // 主线程执行其他任务 48 | doSomethingElse(); 49 | 50 | // 主线程结束时通知捕获线程关闭 51 | stopCapture(); 52 | } finally { 53 | // 确保资源最终被关闭 54 | grabber.release(); 55 | recorder.release(); 56 | } 57 | } 58 | 59 | public static void stopCapture() { 60 | capturing = false; 61 | System.out.println("结束捕获屏幕..."); 62 | capturingLatch.countDown(); // 通知捕获线程捕获应停止 63 | } 64 | 65 | private static void captureFrames(FFmpegFrameGrabber grabber, FFmpegFrameRecorder recorder) throws FFmpegFrameRecorder.Exception, FFmpegFrameGrabber.Exception { 66 | while (capturing) { 67 | Frame frame = grabber.grab(); 68 | if (frame != null) { 69 | recorder.record(frame); 70 | } 71 | } 72 | recorder.stop(); 73 | grabber.stop(); 74 | capturingLatch.countDown(); // 通知主线程捕获已完成 75 | } 76 | 77 | private static FFmpegFrameGrabber createFFmpegFrameGrabber(Dimension screenSize) throws FrameGrabber.Exception { 78 | FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("dshow"); 79 | grabber.setFormat("dshow"); 80 | 81 | // 设置固定的帧率 82 | grabber.setFrameRate(30); 83 | 84 | // 设置分辨率 85 | grabber.setImageWidth(screenSize.width); 86 | grabber.setImageHeight(screenSize.height); 87 | 88 | // 设置设备 ID 89 | // 注意: 这里需要替换成您实际使用的虚拟设备名称 90 | grabber.setOption("video_device", "screen-capture-recorder"); // 替换为您实际的设备名称 91 | 92 | return grabber; 93 | } 94 | 95 | private static FFmpegFrameRecorder createFFmpegFrameRecorder(FrameGrabber grabber, Dimension screenSize) throws IOException { 96 | FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("D:/screenRecording/output.mp4", screenSize.width, screenSize.height); 97 | recorder.setFormat("mp4"); 98 | 99 | // 使用H.264编码器 100 | recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); 101 | 102 | // 设置比特率为 2000 kbps (2 Mbps) 103 | recorder.setVideoBitrate(2000 * 1000); 104 | 105 | // 设置帧率为 30 fps 106 | recorder.setFrameRate(30); 107 | 108 | // 设置预设(preset)为 medium 109 | recorder.setOption("preset", "medium"); 110 | 111 | // 设置 CRF (Constant Rate Factor),值越低质量越高,一般建议范围 18-28 112 | recorder.setOption("crf", "23"); 113 | 114 | recorder.setVideoQuality(0.01f); // 这个设置通常不需要,因为我们使用了 CRF 115 | 116 | return recorder; 117 | } 118 | 119 | private static void doSomethingElse() { 120 | // 主线程执行其他任务 121 | try { 122 | // 模拟主线程执行其他任务 123 | Thread.sleep(60000); // 模拟等待60秒 124 | } catch (InterruptedException e) { 125 | Thread.currentThread().interrupt(); 126 | System.err.println("Main thread interrupted."); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ScreenRecorderUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.bytedeco.javacv.FFmpegFrameGrabber; 5 | import org.bytedeco.javacv.FFmpegFrameRecorder; 6 | import org.bytedeco.javacv.Frame; 7 | import org.bytedeco.javacv.FrameGrabber; 8 | import org.bytedeco.javacv.FrameGrabber.Exception; 9 | import org.bytedeco.ffmpeg.global.avcodec; 10 | 11 | import java.awt.*; 12 | import java.util.concurrent.ExecutorService; 13 | import java.util.concurrent.Executors; 14 | import java.util.concurrent.TimeUnit; 15 | @Slf4j 16 | public class ScreenRecorderUtil { 17 | 18 | private static final ExecutorService executor = Executors.newSingleThreadExecutor(); 19 | private static volatile boolean recording = false; 20 | 21 | public static void main(String[] args) { 22 | try { 23 | startRecording(); 24 | } catch (Exception e) { 25 | e.printStackTrace(); 26 | } catch (FFmpegFrameRecorder.Exception e) { 27 | throw new RuntimeException(e); 28 | } 29 | } 30 | 31 | public static void startRecording() throws Exception, FFmpegFrameRecorder.Exception { 32 | System.setProperty("java.awt.headless", "false"); 33 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 34 | 35 | FrameGrabber grabber = createFFmpegFrameGrabber(screenSize); 36 | FFmpegFrameRecorder recorder = createFFmpegFrameRecorder(grabber); 37 | 38 | try { 39 | grabber.start(); 40 | recorder.start(); 41 | 42 | recording = true; 43 | log.info("开始录制屏幕"); 44 | executor.submit(() -> { 45 | try { 46 | recordFrames(grabber, recorder); 47 | } catch (FFmpegFrameRecorder.Exception | Exception e) { 48 | throw new RuntimeException(e); 49 | } 50 | }); 51 | 52 | // 在这里可以添加用户界面或者其他逻辑来控制录制的开始和停止 53 | // 例如,你可以在这里监听一个按键事件来停止录制 54 | // 为了演示,这里简单地使用一个线程睡眠来模拟用户操作 55 | try { 56 | TimeUnit.SECONDS.sleep(10); // 模拟用户等待60秒后停止录制 57 | } catch (InterruptedException e) { 58 | Thread.currentThread().interrupt(); 59 | System.err.println("Recording thread interrupted."); 60 | } 61 | } finally { 62 | stopRecording(); 63 | } 64 | } 65 | 66 | public static void stopRecording() { 67 | recording = false; 68 | } 69 | 70 | private static void recordFrames(FrameGrabber grabber, FFmpegFrameRecorder recorder) throws Exception, FFmpegFrameRecorder.Exception { 71 | while (recording) { 72 | // log.info("录制屏幕中"); 73 | // 获取屏幕捕捉的一帧 74 | Frame frame = grabber.grabFrame(); 75 | // 将这帧放到录制 76 | if (frame != null) { 77 | recorder.record(frame); 78 | } 79 | } 80 | if(!recording){ 81 | log.info("结束屏幕录制"); 82 | recorder.stop(); 83 | grabber.stop(); 84 | // 确保资源最终被关闭 85 | grabber.release(); 86 | recorder.release(); 87 | } 88 | // 等待录制线程结束 89 | executor.shutdown(); 90 | try { 91 | // 给录制线程一些时间来优雅地结束 92 | if (!executor.awaitTermination(5, TimeUnit.SECONDS)) { 93 | // 如果录制线程没有在5秒内结束,则强制取消 94 | executor.shutdownNow(); 95 | } 96 | } catch (InterruptedException e) { 97 | // 如果主线程被中断,确保中断状态被恢复 98 | Thread.currentThread().interrupt(); 99 | // 强制取消录制线程 100 | executor.shutdownNow(); 101 | } 102 | } 103 | 104 | private static FFmpegFrameGrabber createFFmpegFrameGrabber(Dimension screenSize) throws Exception { 105 | FFmpegFrameGrabber grabber; 106 | String osName = System.getProperty("os.name").toLowerCase(); 107 | if (osName.contains("windows")) { 108 | grabber = new FFmpegFrameGrabber("desktop"); 109 | grabber.setFormat("gdigrab"); 110 | // grabber = new FFmpegFrameGrabber("avfoundation"); 111 | // grabber.setFormat("avfoundation"); 112 | // grabber = new FFmpegFrameGrabber("dshow"); 113 | // grabber.setFormat("dshow"); 114 | } else { 115 | grabber = new FFmpegFrameGrabber("x11grab"); 116 | grabber.setFormat("x11grab"); 117 | } 118 | // 设置固定的帧率 119 | grabber.setFrameRate(30); 120 | // 增加探针大小为10MB 121 | grabber.setOption("probesize", "10000000"); 122 | // 增加缓冲区大小10MB 123 | grabber.setOption("bufsize", "10000000"); 124 | // 设置分辨率 125 | grabber.setImageWidth(screenSize.width); 126 | grabber.setImageHeight(screenSize.height); 127 | 128 | grabber.setOption("offset_x", "0"); 129 | grabber.setOption("offset_y", "0"); 130 | // // 设置设备 ID 131 | // grabber.setDeviceId("video=\"screen-capture-recorder\""); // 这里的设备名需要替换为您实际使用的设备名 132 | // // 设置设备 ID 133 | // grabber.setDeviceIndex(0); // 对于屏幕捕获,设备索引通常是 0 134 | // 设置设备 ID 135 | grabber.setOption("list_devices", "true"); // 列出可用的设备 136 | grabber.setOption("framerate", "30"); // 设置帧率 137 | grabber.setOption("video_device", "0"); // 设备索引通常是 0 对于屏幕捕获 138 | grabber.setOption("pixel_format", "bgr24"); // 设置像素格式 139 | grabber.setOption("format", "avfoundation"); // 设置格式 140 | grabber.setOption("video_size", screenSize.width + "x" + screenSize.height); // 设置视频大小 141 | return grabber; 142 | } 143 | 144 | private static FFmpegFrameRecorder createFFmpegFrameRecorder(FrameGrabber grabber) { 145 | FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("D:/screenRecoding/output.mp4", grabber.getImageWidth(), grabber.getImageHeight()); 146 | recorder.setFormat("mp4"); 147 | // 使用H.264编码器 148 | recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); 149 | // 设置比特率为 5000 kbps (2 Mbps) 150 | recorder.setVideoBitrate(5000 * 1000); 151 | // 设置帧率为 30 fps 152 | recorder.setFrameRate(30); 153 | // 设置预设(preset)为 medium 154 | recorder.setOption("preset", "medium"); 155 | // 设置 CRF (Constant Rate Factor),值越低质量越高,一般建议范围 18-28 156 | recorder.setOption("crf", "23"); 157 | // 这个设置通常不需要,因为我们使用了 CRF 158 | recorder.setVideoQuality(0.01f); 159 | return recorder; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/SystemOutUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.PrintStream; 5 | 6 | /** 7 | * @author 刘智King 8 | * @date 2020年10月22日 下午2:32:46 9 | */ 10 | public class SystemOutUtil { 11 | 12 | public static void main(String[] args) throws FileNotFoundException { 13 | PrintStream print = new PrintStream("Logs/log.txt"); 14 | System.setOut(print); 15 | System.out.print("Reallly?"); 16 | System.out.println("Yes"); 17 | System.out.println("So easy"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/ZipUtil.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import java.io.*; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | import java.nio.file.Paths; 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | import java.util.zip.*; 15 | 16 | public class ZipUtil { 17 | static Logger log = Logger.getLogger(ZipUtil.class); 18 | /** 19 | * 将文件或文件夹压缩成ZIP格式 20 | * 21 | * @param sourceFile 要压缩的文件或文件夹路径 22 | * @param zipFilePath 压缩后的ZIP文件路径 23 | * @throws IOException 如果发生I/O错误 24 | */ 25 | public static void toZip(String sourceFile, String zipFilePath) throws IOException { 26 | ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFilePath))); 27 | File source = new File(sourceFile); 28 | zipFile(zos, source, ""); 29 | zos.close(); 30 | } 31 | 32 | /** 33 | * 递归压缩文件和文件夹 34 | * 35 | * @param zos ZIP输出流 36 | * @param source 要压缩的文件或文件夹 37 | * @param baseFolder 基础文件夹路径 38 | * @throws IOException 如果发生I/O错误 39 | */ 40 | private static void zipFile(ZipOutputStream zos, File source, String baseFolder) throws IOException { 41 | if (source.isDirectory()) { 42 | File[] sourceFiles = source.listFiles(); 43 | if (sourceFiles != null) { 44 | for (File file : sourceFiles) { 45 | zipFile(zos, file, source.getName() + "/"); 46 | } 47 | } 48 | } else { 49 | String path = (baseFolder + source.getName()).replace("\\", "/"); 50 | ZipEntry zipEntry = new ZipEntry(path); 51 | zos.putNextEntry(zipEntry); 52 | FileInputStream fis = new FileInputStream(source); 53 | byte[] bytes = new byte[1024]; 54 | int length; 55 | while ((length = fis.read(bytes)) >= 0) { 56 | zos.write(bytes, 0, length); 57 | } 58 | fis.close(); 59 | } 60 | } 61 | 62 | /** 63 | * 解压ZIP文件 64 | * 65 | * @param zipFilePath ZIP文件路径 66 | * @param destDir 解压后的目录路径 67 | * @return 返回所有文件名的列表 68 | * @throws IOException 如果发生I/O错误 69 | */ 70 | public static List unzip(String zipFilePath, String destDir) throws IOException { 71 | List fileNames = new ArrayList<>(); 72 | 73 | try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(Paths.get(zipFilePath)))) { 74 | ZipEntry zipEntry = zis.getNextEntry(); 75 | int count; 76 | byte[] buffer = new byte[8192]; // 调整缓冲区大小 77 | 78 | File dir = new File(destDir); 79 | if (!dir.exists() && !dir.mkdirs()) { 80 | throw new IOException("Could not create directory: " + dir); 81 | } 82 | 83 | while (zipEntry != null) { 84 | String zipEntryName = zipEntry.getName(); 85 | // 防止路径遍历攻击 86 | Path entryPath = Paths.get(destDir, zipEntryName); 87 | if (!entryPath.normalize().startsWith(Paths.get(destDir).normalize())) { 88 | throw new IOException("Invalid zip entry path: " + zipEntryName); 89 | } 90 | 91 | String filePath = entryPath.toString(); 92 | if (zipEntry.isDirectory()) { 93 | File dirPath = new File(filePath); 94 | if (!dirPath.exists() && !dirPath.mkdirs()) { 95 | throw new IOException("Could not create directory: " + dirPath); 96 | } 97 | } else { 98 | try (FileOutputStream fos = new FileOutputStream(filePath)) { 99 | while ((count = zis.read(buffer)) != -1) { 100 | fos.write(buffer, 0, count); 101 | } 102 | } 103 | fileNames.add(zipEntryName); // 收集文件名 104 | } 105 | zipEntry = zis.getNextEntry(); 106 | } 107 | } catch (IOException e) { 108 | log.error("Error reading zip file: " + zipFilePath); 109 | throw new IOException("Error reading zip file: " + zipFilePath, e); 110 | } 111 | return fileNames; 112 | } 113 | 114 | public static void main(String[] args) { 115 | try { 116 | // 使用示例:将文件夹压缩成ZIP 117 | String sourceFolder = "D:/敏感发现结果.xlsx"; 118 | String zipFile = "D:/敏感发现结果.zip"; 119 | ZipUtil.toZip(sourceFolder, zipFile); 120 | 121 | // 使用示例:解压ZIP文件 122 | String zipFilePath = "D:/敏感发现结果.zip"; 123 | String destDir = "D:/"; 124 | List fileNames1 = ZipUtil.unzip(zipFilePath, destDir); 125 | log.info(fileNames1); 126 | // 打印所有文件名 127 | for (String fileName : fileNames1) { 128 | log.info(fileName); 129 | } 130 | List fileNames = Arrays.asList( 131 | "敏感发现结果1.xlsx", 132 | "敏感发现结果2.xlsx", 133 | "敏感发现结果3.xlsx", 134 | "其他结果.xlsx", 135 | "敏感发现报告.xlsx" 136 | ); 137 | // 正则表达式模式,用于匹配文件名中的序号 138 | Pattern pattern = Pattern.compile("^(.*敏感发现.*)$"); 139 | // 用于存储匹配结果的变量 140 | String fileName = null; 141 | // 遍历文件名列表,查找指定序号的文件名 142 | for (String name : fileNames) { 143 | Matcher matcher = pattern.matcher(name); 144 | if (matcher.find()) { 145 | fileName = name; 146 | } 147 | } 148 | log.info(fileName); 149 | } catch (IOException e) { 150 | e.printStackTrace(); 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/com/sakura/util/maintest.java: -------------------------------------------------------------------------------- 1 | package com.sakura.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.apache.log4j.Logger; 9 | 10 | /** 11 | *
TODO(描述该类的作用)
12 | * 13 | * @author 102051 14 | * @email email 15 | * @date 2017年7月28日 上午11:03:31 16 | * @version 1.0 17 | * @since 1.0 18 | */ 19 | public class maintest { 20 | static Logger log = Logger.getLogger(maintest.class); 21 | public static Map localmap = AppiumUtil.localmap; 22 | 23 | @SuppressWarnings({ "rawtypes", "unchecked" }) 24 | public static void main(String[] args) throws Exception{ 25 | List> st = new ArrayList<>(); 26 | Map map = new HashMap(); 27 | map.put("A", "1"); 28 | map.put("B", "2"); 29 | 30 | Map map1 = new HashMap(); 31 | map1.put("C", "3"); 32 | map1.put("D", "4"); 33 | 34 | Map map2 = new HashMap(); 35 | map2.put("E", "3"); 36 | map2.put("F", "4"); 37 | map2.put("G", map1); 38 | 39 | st.add(map); 40 | st.add(map2); 41 | 42 | List p = new ArrayList<>(); 43 | p.add("5"); 44 | p.add("6"); 45 | 46 | localmap.put("RR", p); 47 | localmap.put("SS", "ok"); 48 | localmap.put("TT",st); 49 | 50 | log.info(AppiumUtil.parseStringHasEls("rr[1]}")); 51 | log.info(AppiumUtil.parseStringHasEls("${rr[1]}")); 52 | log.info(AppiumUtil.parseStringHasEls("${ss}")); 53 | log.info(AppiumUtil.parseEL("${tt[0]}")); 54 | log.info(AppiumUtil.parseEL("${tt}")); 55 | log.info(AppiumUtil.parseEL("${tt[0].a}")); 56 | log.info(AppiumUtil.parseEL("${tt.g.c}")); 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/log4j.properties: -------------------------------------------------------------------------------- 1 | ### log4j设置 ### 2 | log4j.rootLogger = info,console,D,E 3 | 4 | # 输出信息到控制台 ### 5 | #https://blog.csdn.net/shewmi/article/details/78992458 修改控制台日志颜色 6 | #https://github.com/mihnita/ansi-econsole 7 | #log4j.appender.console = org.apache.log4j.ConsoleAppender 8 | log4j.appender.console = com.sakura.util.ANSIConsoleAppender 9 | log4j.appender.console.Target = System.out 10 | log4j.appender.console.layout = org.apache.log4j.PatternLayout 11 | log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss.SSS} %m %n 12 | 13 | ### 输出DEBUG 级别以上的日志到=E://logs/log.log ### 14 | #https://bbs.csdn.net/topics/370077095 15 | #DailyRollingFileAppender 每天产生一个日志文件 16 | log4j.appender.D = org.apache.log4j.DailyRollingFileAppender 17 | log4j.appender.D.File = Logs/log.txt 18 | #log4j.appender.D = com.sakura.dmp.util.Log4jUtil 19 | #log4j.appender.D.File = Logs/yyyy-MM-dd/log.log 20 | log4j.appender.D.Append = false 21 | log4j.appender.D.Threshold = INFO 22 | #log4j.appender.D.Threshold = OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL 23 | log4j.appender.D.Encoding =utf-8 24 | log4j.appender.D.layout = org.apache.log4j.PatternLayout 25 | log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] - %l - %L - %m %n 26 | 27 | ### 输出ERROR 级别以上的日志到=E://logs/error.log ### 28 | log4j.appender.E = org.apache.log4j.DailyRollingFileAppender 29 | log4j.appender.E.File =Logs/error.txt 30 | log4j.appender.E.Append = false 31 | log4j.appender.E.Threshold = ERROR 32 | log4j.appender.E.Encoding =utf-8 33 | log4j.appender.E.layout = org.apache.log4j.PatternLayout 34 | log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] - %l - %L - %m %n -------------------------------------------------------------------------------- /src/main/java/lombok.config: -------------------------------------------------------------------------------- 1 | config.stopBubbling=true 2 | 3 | #setter链式调用 4 | clear lombok.accessors.chain 5 | lombok.accessors.chain=true 6 | 7 | #equals hashCode默认调用父类 8 | clear lombok.equalsAndHashCode.callSuper 9 | lombok.equalsAndHashCode.callSuper=CALL 10 | 11 | #equals hashCode出现警告时是否允许 12 | clear lombok.equalsAndHashCode.flagUsage 13 | lombok.equalsAndHashCode.flagUsage=ALLOW 14 | 15 | #toString默认调用父类 16 | clear lombok.toString.callSuper 17 | lombok.toString.callSuper=CALL 18 | 19 | #toString出现警告时是否允许 20 | clear lombok.toString.flagUsage 21 | lombok.toString.flagUsage=ALLOW -------------------------------------------------------------------------------- /src/main/resources/chromedriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/src/main/resources/chromedriver.exe -------------------------------------------------------------------------------- /src/main/resources/geckodriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SakuraTechy/sakura-selenium/2f7c442d0c3cddbfc5e8b9a84529a469f59c1342/src/main/resources/geckodriver.exe -------------------------------------------------------------------------------- /src/main/resources/id_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEAp0+YnDzWovUnZhf1Qo/N0L3oHru4u6TJUKNBAvAZuTy6cK/D 3 | 0HpMtYI7PnryfD9q6cZOb1JWFGN350mT014N/9iEF8g814jAIB/5K5fML+/0dDP4 4 | QAHJh0qEykI2hUyNoDd1XLzLEh23kbpo1aRR9CpEdLAVJkxz23MFj2Ppob8ldZyB 5 | AbagzZBX07zAxsiSS7buE7kMB9yuY9l80PbEORxirQaguD3ndGKH6E1Lj7rdkbDu 6 | HZ/pzK/j9ihZsSr+y5F9S1z+X7sfZcDZu9fz4uee6+PYXe9SqSK1KB4vYbIS4HtM 7 | YT+qORnUZ+7CnMYHLXAV1q+yg9LUscDIJ/KHsQIDAQABAoIBABMQsuc614qCPRcZ 8 | K82F7YIX4dd+tLJNONODhuj6yzOcg/JLVRjwlsUoLfAUuoUGBPzWqCFvVHfGTeeB 9 | LuMrGJVK6uJ64tP8tUfz3MTm61GbGlQTh/pjOb+88hzKJsRR0OGs8Ca9LLbHxB9L 10 | Cp8ttlkIZ/yUBBT1KU6ccMnCLOFNY5dAczwXMKMit22bMxGA+aZocIKiUidAIMM6 11 | oqAn/OLN9ZJ+m1iWfFkRqm+wda74RNm5rBL7SSNvHJRSxmHj4s94YHsZC5WMUs0o 12 | lMS3et5yo2XQ7YoszWSZoSqouIaHT43leDI7fM6z89Lwi1/SRGKzDRA4nq+J0mFC 13 | Du2TbjECgYEA10t1qIdInyPneJIPX53km8w3VZqZjrIt/ToDjIrNmjrNZ/v3/apd 14 | Fc8Yp3jqJeDcgae1GruPXxK8VfJqOnb0zg+5MsC50732f/xYHyLVeXBlt6A+h3bO 15 | dhl+g7KuWNAntbEVXHDzvX4cYy7am5+0jgPP3eRcoZIEhCYwdK+cXOcCgYEAxvGo 16 | VlWZT5p2MAIZ9EN9bWabvfAui62iWddPotf3FIHYOMpq/dqrlb19UCPfd2zZBIBQ 17 | 6h9PVoc1ghrM+aJYCNq5cPPkV8rFBaa44Ij1VEMmYd0eAJUNIZ7lIHI36/wWSlvK 18 | GVvO59sv0LIBJpCNJZ/XWSd3/Q6VWEFeImTsC6cCgYEAneyLRPDfU2TZ4PZ68m92 19 | htX47QE3jJWk6HBKtCgJAw4JKDKKyXbTSzEba5VlZB2agjzLuu1EEMBEiGMGixZB 20 | InokJld6uBhLHbyzwzshDjBlXJnd5C5A6h5vUBmcjCc8Sam4+pMcJ66/Ef4He0pd 21 | /iJLsv9U92uNhoYg2ycJ8pcCgYAw/EXv5CnY0PazAYF0hL24l2BX13EOkZV9O6fv 22 | N/Aty377FNRdZ1+CgmL9vaeDl3ikRBgoXcdCTg6d142LFi9JFto8dsFN4K68on25 23 | Q9/sfJBR3olJqWnPUnmmkJk2cR7n9kwADHwY2P6gC4R/A27NydrTqAVCeTnKvmW4 24 | YFNC1wKBgQC5fNJq0DpaBeazM/vBth5HmUvA86539wpSjuqsthtMWLdAWs9zlS86 25 | FsGCP/cKmYPTP+FdShKAIXET/e4fOUU6ADugv8sDlir+cfWIO3Aq2sefWUX3bGMn 26 | nKBDSq1OphO9LJ4EqihcYVWparO/lfDxA6xr4QuXCvFzc2P1sIsMnw== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /src/test/java/BD/V1_0_0/TestCaseXml/BD_SMOKE_001.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/test/java/BD/V1_0_0/TestCases/BD_SMOKE_001.java: -------------------------------------------------------------------------------- 1 | package BD.V1_0_0.TestCases; 2 | 3 | import com.sakura.base.TestUnit; 4 | import com.sakura.service.RunUnitService; 5 | import com.sakura.service.WebXmlParseService; 6 | 7 | import org.testng.annotations.AfterTest; 8 | import org.testng.annotations.BeforeTest; 9 | import org.testng.annotations.Parameters; 10 | import org.testng.annotations.Test; 11 | 12 | public class BD_SMOKE_001 { 13 | private static TestUnit testUnit; 14 | 15 | private static WebXmlParseService webXmlParseService; 16 | 17 | private static RunUnitService runService; 18 | 19 | @Parameters({"browser","profile"}) 20 | @BeforeTest 21 | private void setup(String browserName, Boolean profile) throws Exception { 22 | System.out.println(this.getClass().getSimpleName()); 23 | TestUnit testunit = WebXmlParseService.parse(browserName,profile,this.getClass().getPackage().getName(),this.getClass().getSimpleName()); 24 | runService = new RunUnitService(testunit); 25 | } 26 | 27 | @Test( 28 | groups = {"BD_001"} 29 | ) 30 | public void BD_001() throws Exception { 31 | runService.runCase(Thread.currentThread() .getStackTrace()[1].getMethodName()); 32 | } 33 | 34 | @Test( 35 | groups = {"BD_002"} 36 | ) 37 | public void BD_002() throws Exception { 38 | runService.runCase(Thread.currentThread() .getStackTrace()[1].getMethodName()); 39 | } 40 | 41 | @AfterTest 42 | public void TearDown() { 43 | runService.setUnit(true); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/BD/V1_0_0/TestReportXml/172.18.1.118.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/java/TestRunXml/ExtentReport.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | --------------------------------------------------------------------------------