Merge branch 'master' into mcp-client

This commit is contained in:
lilong.129
2025-04-25 17:28:03 +08:00
5 changed files with 86 additions and 24 deletions

View File

@@ -95,7 +95,7 @@ func createBrowserHandler(c *gin.Context) {
return return
} }
browserInfo, err := uixt.CreateBrowser(createBrowserReq.Timeout) browserInfo, err := uixt.CreateBrowser(createBrowserReq.Timeout, createBrowserReq.Width, createBrowserReq.Height)
if err != nil { if err != nil {
RenderError(c, err) RenderError(c, err)
return return

View File

@@ -105,4 +105,6 @@ type ScrollRequest struct {
type CreateBrowserRequest struct { type CreateBrowserRequest struct {
Timeout int `json:"timeout"` Timeout int `json:"timeout"`
Width int `json:"width"`
Height int `json:"height"`
} }

View File

@@ -17,7 +17,7 @@ type BrowserDevice struct {
func NewBrowserDevice(opts ...option.BrowserDeviceOption) (device *BrowserDevice, err error) { func NewBrowserDevice(opts ...option.BrowserDeviceOption) (device *BrowserDevice, err error) {
options := option.NewBrowserDeviceOptions(opts...) options := option.NewBrowserDeviceOptions(opts...)
if options.BrowserID == "" { if options.BrowserID == "" {
browserInfo, err := CreateBrowser(3600) browserInfo, err := CreateBrowser(3600, options.Width, options.Height)
if err != nil { if err != nil {
log.Error().Err(err).Msg("failed to create browser") log.Error().Err(err).Msg("failed to create browser")
return nil, err return nil, err

View File

@@ -43,11 +43,18 @@ type BrowserInfo struct {
ContextId string `json:"context_id"` ContextId string `json:"context_id"`
} }
func CreateBrowser(timeout int) (browserInfo *BrowserInfo, err error) { func CreateBrowser(timeout int, width, height int) (browserInfo *BrowserInfo, err error) {
data := map[string]interface{}{ data := map[string]interface{}{
"timeout": timeout, "timeout": timeout,
} }
if width > 0 && height > 0 {
data["size"] = map[string]int{
"width": width,
"height": height,
}
}
var bsJSON []byte = nil var bsJSON []byte = nil
if bsJSON, err = json.Marshal(data); err != nil { if bsJSON, err = json.Marshal(data); err != nil {
return nil, err return nil, err
@@ -197,7 +204,7 @@ func (wd *BrowserDriver) HoverBySelector(selector string, options ...option.Acti
return err return err
} }
func (wd *BrowserDriver) tapBySelector(selector string, options ...option.ActionOption) (err error) { func (wd *BrowserDriver) TapBySelector(selector string, options ...option.ActionOption) (err error) {
data := map[string]interface{}{ data := map[string]interface{}{
"selector": selector, "selector": selector,
} }
@@ -218,7 +225,7 @@ func (wd *BrowserDriver) RightClick(x, y float64) (err error) {
return err return err
} }
func (wd *BrowserDriver) RightclickbySelector(selector string, options ...option.ActionOption) (err error) { func (wd *BrowserDriver) RightClickBySelector(selector string, options ...option.ActionOption) (err error) {
data := map[string]interface{}{ data := map[string]interface{}{
"selector": selector, "selector": selector,
} }
@@ -232,15 +239,47 @@ func (wd *BrowserDriver) RightclickbySelector(selector string, options ...option
func (wd *BrowserDriver) GetElementTextBySelector(selector string, options ...option.ActionOption) (text string, err error) { func (wd *BrowserDriver) GetElementTextBySelector(selector string, options ...option.ActionOption) (text string, err error) {
actionOptions := option.NewActionOptions(options...) actionOptions := option.NewActionOptions(options...)
uri := "ui/element_text?selector=" + selector baseURL := fmt.Sprintf("http://%s/api/v1/%s/element_text", BROWSER_LOCAL_ADDRESS, wd.sessionId)
// 使用 url.Values 构建查询参数
params := url.Values{}
params.Add("selector", selector)
if actionOptions.Index > 0 { if actionOptions.Index > 0 {
uri = uri + "&element_index=" + fmt.Sprintf("%v", actionOptions.Index) params.Add("element_index", fmt.Sprintf("%v", actionOptions.Index))
} }
resp, err := wd.HttpGet(http.MethodGet, wd.sessionId, uri)
// 构建完整的 URL
uri := fmt.Sprintf("%s?%s", baseURL, params.Encode())
// 使用 http.Get 直接请求
resp, err := http.Get(uri)
if err != nil { if err != nil {
return "", err return "", err
} }
data := resp.Data.(map[string]interface{}) defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", errors.New(resp.Status)
}
rawResp, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
var result WebAgentResponse
if err = json.Unmarshal(rawResp, &result); err != nil {
return "", err
}
if result.Code != 0 {
return "", errors.New(result.Message)
}
data := result.Data.(map[string]interface{})
if data["text"] == nil {
return "", nil
}
return data["text"].(string), nil return data["text"].(string), nil
} }
@@ -408,7 +447,7 @@ func (wd *BrowserDriver) Screen() (Screen, error) {
} }
func (wd *BrowserDriver) Scale() (float64, error) { func (wd *BrowserDriver) Scale() (float64, error) {
return 0, errors.New("not support") return 1, nil
} }
// GetTimestamp returns the timestamp of the mobile device // GetTimestamp returns the timestamp of the mobile device
@@ -418,26 +457,26 @@ func (wd *BrowserDriver) GetTimestamp() (timestamp int64, err error) {
// Homescreen Forces the device under test to switch to the home screen // Homescreen Forces the device under test to switch to the home screen
func (wd *BrowserDriver) Homescreen() error { func (wd *BrowserDriver) Homescreen() error {
return errors.New("not support") return nil
} }
func (wd *BrowserDriver) Unlock() (err error) { func (wd *BrowserDriver) Unlock() (err error) {
return errors.New("not support") return nil
} }
// AppTerminate Terminate an application with the given package name. // AppTerminate Terminate an application with the given package name.
// Either `true` if the app has been successfully terminated or `false` if it was not running // Either `true` if the app has been successfully terminated or `false` if it was not running
func (wd *BrowserDriver) AppTerminate(packageName string) (bool, error) { func (wd *BrowserDriver) AppTerminate(packageName string) (bool, error) {
return false, errors.New("not support") return true, wd.DeleteSession()
} }
// AssertForegroundApp returns nil if the given package and activity are in foreground // AssertForegroundApp returns nil if the given package and activity are in foreground
func (wd *BrowserDriver) AssertForegroundApp(packageName string, activityType ...string) error { func (wd *BrowserDriver) AssertForegroundApp(packageName string, activityType ...string) error {
return errors.New("not support") return nil
} }
func (wd *BrowserDriver) Back() error { func (wd *BrowserDriver) Back() error {
return errors.New("not support") return wd.PressBack()
} }
func (wd *BrowserDriver) AppClear(packageName string) error { func (wd *BrowserDriver) AppClear(packageName string) error {
@@ -474,8 +513,8 @@ func (wd *BrowserDriver) Orientation() (orientation types.Orientation, err error
} }
// Tap Sends a tap event at the coordinate. // Tap Sends a tap event at the coordinate.
func (wd *BrowserDriver) Tap(x, y int, options ...option.ActionOption) error { func (wd *BrowserDriver) Tap(x, y float64, options ...option.ActionOption) error {
return errors.New("not support") return wd.TapFloat(x, y, options...)
} }
func (wd *BrowserDriver) TapFloat(x, y float64, options ...option.ActionOption) error { func (wd *BrowserDriver) TapFloat(x, y float64, options ...option.ActionOption) error {
@@ -523,11 +562,12 @@ func (wd *BrowserDriver) TouchAndHold(x, y float64, options ...option.ActionOpti
// Swipe works like Drag, but `pressForDuration` value is 0 // Swipe works like Drag, but `pressForDuration` value is 0
func (wd *BrowserDriver) Swipe(fromX, fromY, toX, toY float64, options ...option.ActionOption) error { func (wd *BrowserDriver) Swipe(fromX, fromY, toX, toY float64, options ...option.ActionOption) error {
return errors.New("not support") log.Info().Msg(fmt.Sprintf("swipe from (%v, %v) to (%v, %v)", fromX, fromY, toX, toY))
return wd.Drag(fromX, fromY, toX, toY, options...)
} }
func (wd *BrowserDriver) SwipeFloat(fromX, fromY, toX, toY float64, options ...option.ActionOption) error { func (wd *BrowserDriver) SwipeFloat(fromX, fromY, toX, toY float64, options ...option.ActionOption) error {
return errors.New("not support") return wd.Drag(fromX, fromY, toX, toY, options...)
} }
func (wd *BrowserDriver) SetIme(ime string) error { func (wd *BrowserDriver) SetIme(ime string) error {
@@ -611,7 +651,7 @@ func (wd *BrowserDriver) StartCaptureLog(identifier ...string) (err error) {
} }
func (wd *BrowserDriver) StopCaptureLog() (result interface{}, err error) { func (wd *BrowserDriver) StopCaptureLog() (result interface{}, err error) {
return nil, errors.New("not support") return nil, nil
} }
func (wd *BrowserDriver) RecordScreen(folderPath string, duration time.Duration) (videoPath string, err error) { func (wd *BrowserDriver) RecordScreen(folderPath string, duration time.Duration) (videoPath string, err error) {
@@ -623,7 +663,7 @@ func (wd *BrowserDriver) TearDown() error {
} }
func (wd *BrowserDriver) InitSession(capabilities option.Capabilities) error { func (wd *BrowserDriver) InitSession(capabilities option.Capabilities) error {
return errors.New("not support") return nil
} }
func (wd *BrowserDriver) GetSession() *DriverSession { func (wd *BrowserDriver) GetSession() *DriverSession {
@@ -639,15 +679,20 @@ func (wd *BrowserDriver) Rotation() (rotation types.Rotation, err error) {
} }
func (wd *BrowserDriver) SetRotation(rotation types.Rotation) error { func (wd *BrowserDriver) SetRotation(rotation types.Rotation) error {
return errors.New("not support") return nil
} }
func (wd *BrowserDriver) Home() error { func (wd *BrowserDriver) Home() error {
return errors.New("not support") return nil
} }
func (wd *BrowserDriver) TapXY(x, y float64, opts ...option.ActionOption) error { func (wd *BrowserDriver) TapXY(x, y float64, opts ...option.ActionOption) error {
return errors.New("not support") data := map[string]interface{}{
"x": x,
"y": y,
}
_, err := wd.HttpPOST(data, wd.sessionId, "ui/double_tap")
return err
} }
func (wd *BrowserDriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error { func (wd *BrowserDriver) TapAbsXY(x, y float64, opts ...option.ActionOption) error {

View File

@@ -11,6 +11,8 @@ func NewBrowserDeviceOptions(opts ...BrowserDeviceOption) *BrowserDeviceOptions
type BrowserDeviceOptions struct { type BrowserDeviceOptions struct {
BrowserID string `json:"browser_id,omitempty" yaml:"browser_id,omitempty"` BrowserID string `json:"browser_id,omitempty" yaml:"browser_id,omitempty"`
LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"` LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"`
Width int `json:"width,omitempty" yaml:"width,omitempty"`
Height int `json:"height,omitempty" yaml:"height,omitempty"`
} }
type BrowserDeviceOption func(*BrowserDeviceOptions) type BrowserDeviceOption func(*BrowserDeviceOptions)
@@ -20,3 +22,16 @@ func WithBrowserID(serial string) BrowserDeviceOption {
device.BrowserID = serial device.BrowserID = serial
} }
} }
func WithBrowserLogOn(logOn bool) BrowserDeviceOption {
return func(device *BrowserDeviceOptions) {
device.LogOn = logOn
}
}
func WithBrowserPageSize(width, height int) BrowserDeviceOption {
return func(device *BrowserDeviceOptions) {
device.Width = width
device.Height = height
}
}