mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 23:51:25 +08:00
refactor: remove ext install
This commit is contained in:
@@ -15,7 +15,6 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -383,57 +382,6 @@ func GetCurrentDay() string {
|
|||||||
return formattedDate
|
return formattedDate
|
||||||
}
|
}
|
||||||
|
|
||||||
func DownloadFile(filePath string, fileUrl string) error {
|
|
||||||
log.Info().Str("filePath", filePath).Str("url", fileUrl).Msg("download file")
|
|
||||||
parsedURL, err := url.Parse(fileUrl)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := os.Create(filePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer out.Close()
|
|
||||||
|
|
||||||
// 创建一个新的 HTTP 请求
|
|
||||||
req, err := http.NewRequest("GET", fileUrl, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: rename token
|
|
||||||
eapiToken := os.Getenv("EAPI_TOKEN")
|
|
||||||
if eapiToken != "" {
|
|
||||||
if parsedURL.Host != "gtf-eapi-cn.bytedance.com" && parsedURL.Host != "gtf-eapi-cn.bytedance.net" {
|
|
||||||
return errors.New("invalid domain: must be gtf-eapi-cn.bytedance.com")
|
|
||||||
}
|
|
||||||
// 添加自定义头部
|
|
||||||
req.Header.Add("accessKey", "ies.vedem.video")
|
|
||||||
req.Header.Add("token", eapiToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建一个 HTTP 客户端并发送请求
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return fmt.Errorf("bad status: %s, download failed", resp.Status)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将响应主体写入文件
|
|
||||||
_, err = io.Copy(out, resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fileExists(filepath string) bool {
|
func fileExists(filepath string) bool {
|
||||||
_, err := os.Stat(filepath)
|
_, err := os.Stat(filepath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v5.0.0+2502112106
|
v5.0.0+2502112149
|
||||||
|
|||||||
@@ -287,6 +287,12 @@ func (dev *AndroidDevice) installViaInstaller(apkPath string, args ...string) er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InstallResult struct {
|
||||||
|
Result int `json:"result"`
|
||||||
|
ErrorCode int `json:"errorCode"`
|
||||||
|
ErrorMsg string `json:"errorMsg"`
|
||||||
|
}
|
||||||
|
|
||||||
func (dev *AndroidDevice) installCommon(apkPath string, args ...string) error {
|
func (dev *AndroidDevice) installCommon(apkPath string, args ...string) error {
|
||||||
_, err := dev.Device.InstallAPK(apkPath, args...)
|
_, err := dev.Device.InstallAPK(apkPath, args...)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -546,39 +545,3 @@ func (ud *UIA2Driver) Source(srcOpt ...option.SourceOption) (source string, err
|
|||||||
source = reply.Value
|
source = reply.Value
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ud *UIA2Driver) sourceTree(srcOpt ...option.SourceOption) (sourceTree *Hierarchy, err error) {
|
|
||||||
source, err := ud.Source()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sourceTree = new(Hierarchy)
|
|
||||||
err = xml.Unmarshal([]byte(source), sourceTree)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ud *UIA2Driver) TapByText(text string, opts ...option.ActionOption) error {
|
|
||||||
sourceTree, err := ud.sourceTree()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return ud.tapByTextUsingHierarchy(sourceTree, text, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ud *UIA2Driver) TapByTexts(actions ...TapTextAction) error {
|
|
||||||
sourceTree, err := ud.sourceTree()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, action := range actions {
|
|
||||||
err := ud.tapByTextUsingHierarchy(sourceTree, action.Text, action.Options...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -105,13 +105,6 @@ func TestDriver_Source(t *testing.T) {
|
|||||||
t.Log(source)
|
t.Log(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDriver_TapByText(t *testing.T) {
|
|
||||||
err := driver.TapByText("安装")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDriver_BatteryInfo(t *testing.T) {
|
func TestDriver_BatteryInfo(t *testing.T) {
|
||||||
batteryInfo, err := driver.BatteryInfo()
|
batteryInfo, err := driver.BatteryInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -342,39 +335,6 @@ func TestDriver_ShellInputUnicode(t *testing.T) {
|
|||||||
t.Log(os.WriteFile("s1.png", raw.Bytes(), 0o600))
|
t.Log(os.WriteFile("s1.png", raw.Bytes(), 0o600))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTapTexts(t *testing.T) {
|
|
||||||
setupAndroidUIA2Driver(t)
|
|
||||||
actions := []TapTextAction{
|
|
||||||
{
|
|
||||||
Text: "^.*无视风险安装$",
|
|
||||||
Options: []option.ActionOption{
|
|
||||||
option.WithTapOffset(100, 0),
|
|
||||||
option.WithRegex(true),
|
|
||||||
option.WithIgnoreNotFoundError(true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Text: "已了解此应用未经检测.*",
|
|
||||||
Options: []option.ActionOption{
|
|
||||||
option.WithTapOffset(-450, 0),
|
|
||||||
option.WithRegex(true),
|
|
||||||
option.WithIgnoreNotFoundError(true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Text: "^(.*无视风险安装|确定|继续|完成|点击继续安装|继续安装旧版本|替换|安装|授权本次安装|继续安装|重新安装)$",
|
|
||||||
Options: []option.ActionOption{
|
|
||||||
option.WithRegex(true),
|
|
||||||
option.WithIgnoreNotFoundError(true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := driverExt.TapByTexts(actions...)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRecordVideo(t *testing.T) {
|
func TestRecordVideo(t *testing.T) {
|
||||||
setupAndroidAdbDriver(t)
|
setupAndroidAdbDriver(t)
|
||||||
path, err := driverExt.ScreenRecord(5 * time.Second)
|
path, err := driverExt.ScreenRecord(5 * time.Second)
|
||||||
|
|||||||
@@ -62,8 +62,6 @@ type IDriver interface {
|
|||||||
TapAbsXY(x, y float64, opts ...option.ActionOption) error // by absolute coordinate
|
TapAbsXY(x, y float64, opts ...option.ActionOption) error // by absolute coordinate
|
||||||
DoubleTapXY(x, y float64, opts ...option.ActionOption) error // by percentage
|
DoubleTapXY(x, y float64, opts ...option.ActionOption) error // by percentage
|
||||||
TouchAndHold(x, y float64, opts ...option.ActionOption) error
|
TouchAndHold(x, y float64, opts ...option.ActionOption) error
|
||||||
TapByText(text string, opts ...option.ActionOption) error // TODO: remove
|
|
||||||
TapByTexts(actions ...TapTextAction) error // TODO: remove
|
|
||||||
// swipe
|
// swipe
|
||||||
Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
Drag(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
|
||||||
Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error // by percentage
|
Swipe(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error // by percentage
|
||||||
@@ -104,9 +102,6 @@ type IDriverExt interface {
|
|||||||
|
|
||||||
CheckPopup() (popup *PopupInfo, err error)
|
CheckPopup() (popup *PopupInfo, err error)
|
||||||
ClosePopupsHandler() error
|
ClosePopupsHandler() error
|
||||||
|
|
||||||
DoAction(action MobileAction) error
|
|
||||||
DoValidation(check, assert, expected string, message ...string) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type XTDriver struct {
|
type XTDriver struct {
|
||||||
|
|||||||
@@ -137,15 +137,15 @@ func (dExt *XTDriver) DoAction(action MobileAction) (err error) {
|
|||||||
|
|
||||||
switch action.Method {
|
switch action.Method {
|
||||||
case ACTION_AppInstall:
|
case ACTION_AppInstall:
|
||||||
if appUrl, ok := action.Params.(string); ok {
|
if app, ok := action.Params.(string); ok {
|
||||||
if err = dExt.InstallByUrl(appUrl,
|
if err = dExt.GetDevice().Install(app,
|
||||||
option.WithRetryTimes(action.MaxRetryTimes)); err != nil {
|
option.WithRetryTimes(action.MaxRetryTimes)); err != nil {
|
||||||
return errors.Wrap(err, "failed to install app")
|
return errors.Wrap(err, "failed to install app")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ACTION_AppUninstall:
|
case ACTION_AppUninstall:
|
||||||
if packageName, ok := action.Params.(string); ok {
|
if packageName, ok := action.Params.(string); ok {
|
||||||
if err = dExt.Uninstall(packageName, action.GetOptions()...); err != nil {
|
if err = dExt.GetDevice().Uninstall(packageName); err != nil {
|
||||||
return errors.Wrap(err, "failed to uninstall app")
|
return errors.Wrap(err, "failed to uninstall app")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
package uixt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
|
|
||||||
"github.com/httprunner/httprunner/v5/internal/builtin"
|
|
||||||
"github.com/httprunner/httprunner/v5/pkg/uixt/option"
|
|
||||||
)
|
|
||||||
|
|
||||||
type InstallResult struct {
|
|
||||||
Result int `json:"result"`
|
|
||||||
ErrorCode int `json:"errorCode"`
|
|
||||||
ErrorMsg string `json:"errorMsg"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dExt *XTDriver) InstallByUrl(url string, opts ...option.InstallOption) error {
|
|
||||||
// 获取当前目录
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将文件保存到当前目录
|
|
||||||
appPath := filepath.Join(cwd, fmt.Sprint(time.Now().UnixNano())) // 替换为你想保存的文件名
|
|
||||||
err = builtin.DownloadFile(appPath, url)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("download file failed")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = dExt.Install(appPath, opts...)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("install app failed")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dExt *XTDriver) Install(filePath string, opts ...option.InstallOption) error {
|
|
||||||
if _, ok := dExt.GetDevice().(*AndroidDevice); ok {
|
|
||||||
stopChan := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
ticker := time.NewTicker(5 * time.Second)
|
|
||||||
defer ticker.Stop()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ticker.C:
|
|
||||||
actions := []TapTextAction{
|
|
||||||
{
|
|
||||||
Text: "^.*无视风险安装$",
|
|
||||||
Options: []option.ActionOption{
|
|
||||||
option.WithTapOffset(100, 0),
|
|
||||||
option.WithRegex(true),
|
|
||||||
option.WithIgnoreNotFoundError(true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Text: "^已了解此应用未经检测.*",
|
|
||||||
Options: []option.ActionOption{
|
|
||||||
option.WithTapOffset(-450, 0),
|
|
||||||
option.WithRegex(true),
|
|
||||||
option.WithIgnoreNotFoundError(true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
_ = dExt.TapByTexts(actions...)
|
|
||||||
|
|
||||||
_ = dExt.TapByOCR(
|
|
||||||
"^(.*无视风险安装|确定|继续|完成|点击继续安装|继续安装旧版本|替换|授权本次安装|稍后提醒|继续安装|重新安装|安装)$",
|
|
||||||
option.WithRegex(true),
|
|
||||||
option.WithIgnoreNotFoundError(true),
|
|
||||||
)
|
|
||||||
case <-stopChan:
|
|
||||||
log.Info().Msg("Ticker stopped")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
defer func() {
|
|
||||||
close(stopChan)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
return dExt.GetDevice().Install(filePath, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dExt *XTDriver) Uninstall(packageName string, opts ...option.ActionOption) error {
|
|
||||||
actionOptions := option.NewActionOptions(opts...)
|
|
||||||
err := dExt.GetDevice().Uninstall(packageName)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn().Err(err).Msg("failed to uninstall")
|
|
||||||
}
|
|
||||||
if actionOptions.IgnoreNotFoundError {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -255,14 +255,6 @@ func (hd *HDCDriver) Source(srcOpt ...option.SourceOption) (string, error) {
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hd *HDCDriver) TapByText(text string, opts ...option.ActionOption) error {
|
|
||||||
return types.ErrDriverNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hd *HDCDriver) TapByTexts(actions ...TapTextAction) error {
|
|
||||||
return types.ErrDriverNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hd *HDCDriver) StartCaptureLog(identifier ...string) (err error) {
|
func (hd *HDCDriver) StartCaptureLog(identifier ...string) (err error) {
|
||||||
return types.ErrDriverNotImplemented
|
return types.ErrDriverNotImplemented
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -770,14 +770,6 @@ func (wd *WDADriver) Source(srcOpt ...option.SourceOption) (source string, err e
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wd *WDADriver) TapByText(text string, opts ...option.ActionOption) error {
|
|
||||||
return types.ErrDriverNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WDADriver) TapByTexts(actions ...TapTextAction) error {
|
|
||||||
return types.ErrDriverNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WDADriver) AccessibleSource() (source string, err error) {
|
func (wd *WDADriver) AccessibleSource() (source string, err error) {
|
||||||
// [[FBRoute GET:@"/wda/accessibleSource"] respondWithTarget:self action:@selector(handleGetAccessibleSourceCommand:)]
|
// [[FBRoute GET:@"/wda/accessibleSource"] respondWithTarget:self action:@selector(handleGetAccessibleSourceCommand:)]
|
||||||
// [[FBRoute GET:@"/wda/accessibleSource"].withoutSession
|
// [[FBRoute GET:@"/wda/accessibleSource"].withoutSession
|
||||||
|
|||||||
Reference in New Issue
Block a user