From 9add5df1b24d633fd3d5ab306c4e113352dc18be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=99=E6=B3=93=E9=93=AE?= Date: Thu, 24 Jul 2025 17:06:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=89=AA=E8=B4=B4=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uixt/android_driver_adb.go | 54 ++++++++++++++++++++++++++++++++++++++ uixt/android_test.go | 7 +++++ uixt/ios_driver_wda.go | 8 ++++-- uixt/ios_test.go | 7 +++++ uixt/option/android.go | 5 ++-- 5 files changed, 77 insertions(+), 4 deletions(-) diff --git a/uixt/android_driver_adb.go b/uixt/android_driver_adb.go index 1e539364..0f54b9c3 100644 --- a/uixt/android_driver_adb.go +++ b/uixt/android_driver_adb.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "context" + "encoding/base64" "encoding/json" "encoding/xml" "fmt" @@ -1166,6 +1167,59 @@ func (ad *ADBDriver) ClearFiles(paths ...string) error { return nil } +func (ad *ADBDriver) GetPasteboard() (content string, err error) { + /** + adb shell am broadcast -n io.appium.settings/.receivers.ClipboardReceiver -a io.appium.settings.clipboard.get + Broadcasting: Intent { act=io.appium.settings.clipboard.get flg=0x400000 cmp=io.appium.settings/.receivers.ClipboardReceiver } + Broadcast completed: result=-1, data="SEhHRw==" + **/ + + // Check and switch input method if needed, similar to SendUnicodeKeys + currentIme, err := ad.GetIme() + if err != nil { + return "", err + } + + // If current IME is not the required one, switch temporarily and restore later + if currentIme != option.UnicodeImePackageName { + defer func() { + _ = ad.SetIme(currentIme) + }() + + err = ad.SetIme(option.UnicodeImePackageName) + if err != nil { + log.Warn().Err(err).Msgf("set Unicode Ime failed for clipboard operation") + // Continue anyway, might still work with current IME + } + } + + res, err := ad.Device.RunShellCommand("am", "broadcast", "-n", option.AppiumSettingsPackageName+"/.receivers.ClipboardReceiver", "-a", option.AppiumSettingsPackageName+".clipboard.get") + if err != nil { + return "", err + } + + // Parse the response to extract the base64 encoded data + dataPrefix := "data=\"" + dataIndex := strings.Index(res, dataPrefix) + if dataIndex == -1 { + return "", fmt.Errorf("clipboard data not found in response: %s", res) + } + + dataStart := dataIndex + len(dataPrefix) + dataEnd := strings.Index(res[dataStart:], "\"") + if dataEnd == -1 { + return "", fmt.Errorf("malformed clipboard data in response: %s", res) + } + + base64Data := res[dataStart : dataStart+dataEnd] + decodedData, err := base64.StdEncoding.DecodeString(base64Data) + if err != nil { + return "", fmt.Errorf("failed to decode clipboard content: %w", err) + } + + return string(decodedData), nil +} + type ExportPoint struct { Start int `json:"start" yaml:"start"` End int `json:"end" yaml:"end"` diff --git a/uixt/android_test.go b/uixt/android_test.go index 794b9160..b8a085be 100644 --- a/uixt/android_test.go +++ b/uixt/android_test.go @@ -321,3 +321,10 @@ func TestDriver_UIA2_Input(t *testing.T) { err = driver.Input("123\n") assert.Nil(t, err) } + +func TestDriver_ADB_GetPasteboard(t *testing.T) { + driver := setupADBDriverExt(t) + pasteboard, err := driver.IDriver.(*ADBDriver).GetPasteboard() + assert.Nil(t, err) + t.Log(pasteboard) +} diff --git a/uixt/ios_driver_wda.go b/uixt/ios_driver_wda.go index b7d68474..02be5bac 100644 --- a/uixt/ios_driver_wda.go +++ b/uixt/ios_driver_wda.go @@ -630,9 +630,13 @@ func (wd *WDADriver) SetPasteboard(contentType types.PasteboardType, content str return } -func (wd *WDADriver) GetPasteboard(contentType types.PasteboardType) (raw *bytes.Buffer, err error) { +func (wd *WDADriver) GetPasteboard() (raw *bytes.Buffer, err error) { // [[FBRoute POST:@"/wda/getPasteboard"] respondWithTarget:self action:@selector(handleGetPasteboard:)] - data := map[string]interface{}{"contentType": contentType} + err = wd.AppLaunch("com.gtf.wda.runner.xctrunner") + if err != nil { + return nil, errors.Wrap(err, "GetPasteboard failed. WDA app not launched") + } + data := map[string]interface{}{} var rawResp DriverRawResponse if rawResp, err = wd.Session.POST(data, "/wda/getPasteboard"); err != nil { return nil, err diff --git a/uixt/ios_test.go b/uixt/ios_test.go index 0a0bbde0..6ec08066 100644 --- a/uixt/ios_test.go +++ b/uixt/ios_test.go @@ -356,3 +356,10 @@ func TestDriver_WDA_PushImage(t *testing.T) { err = driver.ClearImages() assert.Nil(t, err) } + +func TestDriver_WDA_GetPasteboard(t *testing.T) { + driver := setupWDADriverExt(t) + pasteboard, err := driver.IDriver.(*WDADriver).GetPasteboard() + assert.Nil(t, err) + t.Log(pasteboard) +} diff --git a/uixt/option/android.go b/uixt/option/android.go index bfa991a6..dc3d4e35 100644 --- a/uixt/option/android.go +++ b/uixt/option/android.go @@ -49,8 +49,9 @@ const ( defaultUIA2ServerPackageName = "io.appium.uiautomator2.server" defaultUIA2ServerTestPackageName = "io.appium.uiautomator2.server.test" - AdbKeyBoardPackageName = "com.android.adbkeyboard/.AdbIME" - UnicodeImePackageName = "io.appium.settings/.UnicodeIME" + AdbKeyBoardPackageName = "com.android.adbkeyboard/.AdbIME" + UnicodeImePackageName = AppiumSettingsPackageName + "/.UnicodeIME" + AppiumSettingsPackageName = "io.appium.settings" ) func NewAndroidDeviceOptions(opts ...AndroidDeviceOption) *AndroidDeviceOptions {