mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-07 00:17:37 +08:00
feat: 支持wings断言和自动化
This commit is contained in:
@@ -3,6 +3,7 @@ package uixt
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mark3labs/mcp-go/mcp"
|
||||
"github.com/mark3labs/mcp-go/server"
|
||||
@@ -393,3 +394,195 @@ func (t *ToolGetForegroundApp) Implement() server.ToolHandlerFunc {
|
||||
func (t *ToolGetForegroundApp) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
|
||||
return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil
|
||||
}
|
||||
|
||||
// ToolOpenApp implements the open_app tool call.
|
||||
type ToolOpenApp struct {
|
||||
// Return data fields - these define the structure of data returned by this tool
|
||||
PackageName string `json:"packageName" desc:"Package name of the opened app"`
|
||||
}
|
||||
|
||||
func (t *ToolOpenApp) Name() option.ActionName {
|
||||
return option.ACTION_OpenApp
|
||||
}
|
||||
|
||||
func (t *ToolOpenApp) Description() string {
|
||||
return "Open an app on mobile device using its package name and wait for the app to load"
|
||||
}
|
||||
|
||||
func (t *ToolOpenApp) Options() []mcp.ToolOption {
|
||||
unifiedReq := &option.ActionOptions{}
|
||||
return unifiedReq.GetMCPOptions(option.ACTION_OpenApp)
|
||||
}
|
||||
|
||||
func (t *ToolOpenApp) Implement() server.ToolHandlerFunc {
|
||||
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
arguments := request.GetArguments()
|
||||
driverExt, err := setupXTDriver(ctx, arguments)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||
}
|
||||
|
||||
unifiedReq, err := parseActionOptions(arguments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if unifiedReq.PackageName == "" {
|
||||
return nil, fmt.Errorf("package_name is required")
|
||||
}
|
||||
|
||||
// Open app action logic
|
||||
err = driverExt.AppLaunch(unifiedReq.PackageName)
|
||||
if err != nil {
|
||||
return NewMCPErrorResponse(fmt.Sprintf("Open app failed: %s", err.Error())), err
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("Successfully opened app: %s", unifiedReq.PackageName)
|
||||
returnData := ToolOpenApp{PackageName: unifiedReq.PackageName}
|
||||
|
||||
return NewMCPSuccessResponse(message, &returnData), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ToolOpenApp) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
|
||||
if packageName, ok := action.Params.(string); ok {
|
||||
arguments := map[string]any{
|
||||
"packageName": packageName,
|
||||
}
|
||||
return BuildMCPCallToolRequest(t.Name(), arguments, action), nil
|
||||
}
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid open app params: %v", action.Params)
|
||||
}
|
||||
|
||||
// ToolTerminateAppNew implements the terminal_app tool call.
|
||||
type ToolTerminateAppNew struct {
|
||||
// Return data fields - these define the structure of data returned by this tool
|
||||
PackageName string `json:"packageName" desc:"Package name of the terminated app"`
|
||||
WasRunning bool `json:"wasRunning" desc:"Whether the app was actually running before termination"`
|
||||
}
|
||||
|
||||
func (t *ToolTerminateAppNew) Name() option.ActionName {
|
||||
return option.ACTION_TerminateApp
|
||||
}
|
||||
|
||||
func (t *ToolTerminateAppNew) Description() string {
|
||||
return "Terminate a running app on mobile device using its package name"
|
||||
}
|
||||
|
||||
func (t *ToolTerminateAppNew) Options() []mcp.ToolOption {
|
||||
unifiedReq := &option.ActionOptions{}
|
||||
return unifiedReq.GetMCPOptions(option.ACTION_TerminateApp)
|
||||
}
|
||||
|
||||
func (t *ToolTerminateAppNew) Implement() server.ToolHandlerFunc {
|
||||
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
arguments := request.GetArguments()
|
||||
driverExt, err := setupXTDriver(ctx, arguments)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||
}
|
||||
|
||||
unifiedReq, err := parseActionOptions(arguments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if unifiedReq.PackageName == "" {
|
||||
return nil, fmt.Errorf("package_name is required")
|
||||
}
|
||||
|
||||
// Terminate app action logic
|
||||
success, err := driverExt.AppTerminate(unifiedReq.PackageName)
|
||||
if err != nil {
|
||||
return NewMCPErrorResponse(fmt.Sprintf("Terminate app failed: %s", err.Error())), err
|
||||
}
|
||||
if !success {
|
||||
log.Warn().Str("packageName", unifiedReq.PackageName).Msg("app was not running")
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("Successfully terminated app: %s", unifiedReq.PackageName)
|
||||
returnData := ToolTerminateAppNew{
|
||||
PackageName: unifiedReq.PackageName,
|
||||
WasRunning: success,
|
||||
}
|
||||
|
||||
return NewMCPSuccessResponse(message, &returnData), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ToolTerminateAppNew) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
|
||||
if packageName, ok := action.Params.(string); ok {
|
||||
arguments := map[string]any{
|
||||
"packageName": packageName,
|
||||
}
|
||||
return BuildMCPCallToolRequest(t.Name(), arguments, action), nil
|
||||
}
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid terminate app params: %v", action.Params)
|
||||
}
|
||||
|
||||
// ToolColdLaunch implements the cold_launch tool call.
|
||||
type ToolColdLaunch struct {
|
||||
// Return data fields - these define the structure of data returned by this tool
|
||||
PackageName string `json:"packageName" desc:"Package name of the cold launched app"`
|
||||
}
|
||||
|
||||
func (t *ToolColdLaunch) Name() option.ActionName {
|
||||
return option.ACTION_ColdLaunch
|
||||
}
|
||||
|
||||
func (t *ToolColdLaunch) Description() string {
|
||||
return "Perform a cold launch of an app (terminate first if running, then launch)"
|
||||
}
|
||||
|
||||
func (t *ToolColdLaunch) Options() []mcp.ToolOption {
|
||||
unifiedReq := &option.ActionOptions{}
|
||||
return unifiedReq.GetMCPOptions(option.ACTION_ColdLaunch)
|
||||
}
|
||||
|
||||
func (t *ToolColdLaunch) Implement() server.ToolHandlerFunc {
|
||||
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
arguments := request.GetArguments()
|
||||
driverExt, err := setupXTDriver(ctx, arguments)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||
}
|
||||
|
||||
unifiedReq, err := parseActionOptions(arguments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if unifiedReq.PackageName == "" {
|
||||
return nil, fmt.Errorf("package_name is required")
|
||||
}
|
||||
|
||||
// Cold launch logic: terminate first, then launch
|
||||
// First try to terminate the app (ignore errors if app is not running)
|
||||
_, err = driverExt.AppTerminate(unifiedReq.PackageName)
|
||||
if err != nil {
|
||||
log.Warn().Str("packageName", unifiedReq.PackageName).Msg("app was not running")
|
||||
return NewMCPErrorResponse(fmt.Sprintf("Cold launch failed, terminate app failed: %s", err.Error())), err
|
||||
}
|
||||
time.Sleep(3 * time.Second)
|
||||
// Then launch the app
|
||||
err = driverExt.AppLaunch(unifiedReq.PackageName)
|
||||
if err != nil {
|
||||
return NewMCPErrorResponse(fmt.Sprintf("Cold launch failed, launch app failed: %s", err.Error())), err
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("Successfully cold launched app: %s", unifiedReq.PackageName)
|
||||
returnData := ToolColdLaunch{PackageName: unifiedReq.PackageName}
|
||||
|
||||
return NewMCPSuccessResponse(message, &returnData), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ToolColdLaunch) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
|
||||
if packageName, ok := action.Params.(string); ok {
|
||||
arguments := map[string]any{
|
||||
"packageName": packageName,
|
||||
}
|
||||
return BuildMCPCallToolRequest(t.Name(), arguments, action), nil
|
||||
}
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid cold launch params: %v", action.Params)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user