Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding an endpoint to run WDA #491

Merged
merged 8 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions ios/testmanagerd/xcuitestrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
"maps"
"path"
"strings"

Expand Down Expand Up @@ -219,7 +220,7 @@ const (

const testBundleSuffix = "UITests.xctrunner"

func RunXCUITest(bundleID string, testRunnerBundleID string, xctestConfigName string, device ios.DeviceEntry, env []string, testsToRun []string, testsToSkip []string, testListener *TestListener, isXCTest bool) ([]TestSuite, error) {
func RunXCUITest(bundleID string, testRunnerBundleID string, xctestConfigName string, device ios.DeviceEntry, env map[string]interface{}, testsToRun []string, testsToSkip []string, testListener *TestListener, isXCTest bool) ([]TestSuite, error) {
// FIXME: this is redundant code, getting the app list twice and creating the appinfos twice
// just to generate the xctestConfigFileName. Should be cleaned up at some point.
installationProxy, err := installationproxy.New(device)
Expand Down Expand Up @@ -256,7 +257,7 @@ func RunXCUIWithBundleIdsCtx(
xctestConfigFileName string,
device ios.DeviceEntry,
args []string,
env []string,
env map[string]interface{},
testsToRun []string,
testsToSkip []string,
testListener *TestListener,
Expand Down Expand Up @@ -288,7 +289,7 @@ func runXUITestWithBundleIdsXcode15Ctx(
xctestConfigFileName string,
device ios.DeviceEntry,
args []string,
env []string,
env map[string]interface{},
testsToRun []string,
testsToSkip []string,
testListener *TestListener,
Expand Down Expand Up @@ -443,7 +444,7 @@ func killTestRunner(killer processKiller, pid int) error {
return nil
}

func startTestRunner17(device ios.DeviceEntry, appserviceConn *appservice.Connection, xctestConfigPath string, bundleID string, sessionIdentifier string, testBundlePath string, testArgs []string, testEnv []string, isXCTest bool) (appservice.LaunchedAppWithStdIo, error) {
func startTestRunner17(device ios.DeviceEntry, appserviceConn *appservice.Connection, xctestConfigPath string, bundleID string, sessionIdentifier string, testBundlePath string, testArgs []string, testEnv map[string]interface{}, isXCTest bool) (appservice.LaunchedAppWithStdIo, error) {
args := []interface{}{}
for _, arg := range testArgs {
args = append(args, arg)
Expand Down Expand Up @@ -471,12 +472,12 @@ func startTestRunner17(device ios.DeviceEntry, appserviceConn *appservice.Connec
"XCTestSessionIdentifier": strings.ToUpper(sessionIdentifier),
}

for _, entrystring := range testEnv {
entry := strings.Split(entrystring, "=")
key := entry[0]
value := entry[1]
env[key] = value
log.Debugf("adding extra env %s=%s", key, value)
if len(testEnv) > 0 {
maps.Copy(env, testEnv)

for key, value := range testEnv {
log.Debugf("adding extra env %s=%s", key, value)
}
}

opts := map[string]interface{}{
Expand Down
18 changes: 9 additions & 9 deletions ios/testmanagerd/xcuitestrunner_11.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package testmanagerd
import (
"context"
"fmt"
"strings"
"maps"

"github.com/danielpaulus/go-ios/ios"
dtx "github.com/danielpaulus/go-ios/ios/dtx_codec"
Expand All @@ -18,7 +18,7 @@ func runXCUIWithBundleIdsXcode11Ctx(
xctestConfigFileName string,
device ios.DeviceEntry,
args []string,
env []string,
env map[string]interface{},
testsToRun []string,
testsToSkip []string,
testListener *TestListener,
Expand Down Expand Up @@ -110,7 +110,7 @@ func runXCUIWithBundleIdsXcode11Ctx(
}

func startTestRunner11(pControl *instruments.ProcessControl, xctestConfigPath string, bundleID string,
sessionIdentifier string, testBundlePath string, wdaargs []string, wdaenv []string,
sessionIdentifier string, testBundlePath string, wdaargs []string, wdaenv map[string]interface{},
) (uint64, error) {
args := []interface{}{}
for _, arg := range wdaargs {
Expand All @@ -122,12 +122,12 @@ func startTestRunner11(pControl *instruments.ProcessControl, xctestConfigPath st
"XCTestSessionIdentifier": sessionIdentifier,
}

for _, entrystring := range wdaenv {
entry := strings.Split(entrystring, "=")
key := entry[0]
value := entry[1]
env[key] = value
log.Debugf("adding extra env %s=%s", key, value)
if len(wdaenv) > 0 {
maps.Copy(env, wdaenv)

for key, value := range wdaenv {
log.Debugf("adding extra env %s=%s", key, value)
}
}

opts := map[string]interface{}{
Expand Down
18 changes: 9 additions & 9 deletions ios/testmanagerd/xcuitestrunner_12.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package testmanagerd
import (
"context"
"fmt"
"strings"
"maps"
"time"

"github.com/danielpaulus/go-ios/ios"
Expand All @@ -14,7 +14,7 @@ import (
)

func runXUITestWithBundleIdsXcode12Ctx(ctx context.Context, bundleID string, testRunnerBundleID string, xctestConfigFileName string,
device ios.DeviceEntry, args []string, env []string, testsToRun []string, testsToSkip []string, testListener *TestListener, isXCTest bool,
device ios.DeviceEntry, args []string, env map[string]interface{}, testsToRun []string, testsToSkip []string, testListener *TestListener, isXCTest bool,
) ([]TestSuite, error) {
conn, err := dtx.NewUsbmuxdConnection(device, testmanagerdiOS14)
if err != nil {
Expand Down Expand Up @@ -108,7 +108,7 @@ func runXUITestWithBundleIdsXcode12Ctx(ctx context.Context, bundleID string, tes
}

func startTestRunner12(pControl *instruments.ProcessControl, xctestConfigPath string, bundleID string,
sessionIdentifier string, testBundlePath string, wdaargs []string, wdaenv []string,
sessionIdentifier string, testBundlePath string, wdaargs []string, wdaenv map[string]interface{},
) (uint64, error) {
args := []interface{}{
"-NSTreatUnknownArgumentsAsOpen", "NO", "-ApplePersistenceIgnoreState", "YES",
Expand All @@ -130,12 +130,12 @@ func startTestRunner12(pControl *instruments.ProcessControl, xctestConfigPath st
"XCTestSessionIdentifier": sessionIdentifier,
}

for _, entrystring := range wdaenv {
entry := strings.Split(entrystring, "=")
key := entry[0]
value := entry[1]
env[key] = value
log.Debugf("adding extra env %s=%s", key, value)
if len(wdaenv) > 0 {
maps.Copy(env, wdaenv)

for key, value := range wdaenv {
log.Debugf("adding extra env %s=%s", key, value)
}
}

opts := map[string]interface{}{
Expand Down
2 changes: 1 addition & 1 deletion ios/testmanagerd/xcuitestrunner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestXcuiTest(t *testing.T) {
ctx, stopWda := context.WithCancel(context.Background())
bundleID, testbundleID, xctestconfig := "com.facebook.WebDriverAgentRunner.xctrunner", "com.facebook.WebDriverAgentRunner.xctrunner", "WebDriverAgentRunner.xctest"
var wdaargs []string
var wdaenv []string
var wdaenv map[string]interface{}
go func() {
_, err := testmanagerd.RunXCUIWithBundleIdsCtx(ctx, bundleID, testbundleID, xctestconfig, device, wdaargs, wdaenv, nil, nil, testmanagerd.NewTestListener(os.Stdout, os.Stdout, os.TempDir()), false)
if err != nil {
Expand Down
16 changes: 13 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -913,8 +913,7 @@ The commands work as following:
}

rawTestlog, rawTestlogErr := arguments.String("--log-output")
env := arguments["--env"].([]string)

env := splitKeyValuePairs(arguments["--env"].([]string), "=")
isXCTest, _ := arguments.Bool("--xctest")

if rawTestlogErr == nil {
Expand Down Expand Up @@ -1191,7 +1190,7 @@ func runWdaCommand(device ios.DeviceEntry, arguments docopt.Opts) bool {
testbundleID, _ := arguments.String("--testrunnerbundleid")
xctestconfig, _ := arguments.String("--xctestconfig")
wdaargs := arguments["--arg"].([]string)
wdaenv := arguments["--env"].([]string)
wdaenv := splitKeyValuePairs(arguments["--env"].([]string), "=")

if bundleID == "" && testbundleID == "" && xctestconfig == "" {
log.Info("no bundle ids specified, falling back to defaults")
Expand Down Expand Up @@ -2186,3 +2185,14 @@ func exitIfError(msg string, err error) {
log.WithFields(log.Fields{"err": err}).Fatalf(msg)
}
}

func splitKeyValuePairs(envArgs []string, sep string) map[string]interface{} {
env := make(map[string]interface{})
for _, entrystring := range envArgs {
entry := strings.Split(entrystring, sep)
key := entry[0]
value := entry[1]
env[key] = value
}
return env
}
43 changes: 43 additions & 0 deletions restapi/api/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"sync"

"github.com/danielpaulus/go-ios/ios"
"github.com/danielpaulus/go-ios/ios/tunnel"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)

// DeviceMiddleware makes sure a udid was specified and that a device with that UDID
Expand All @@ -30,11 +32,52 @@ func DeviceMiddleware() gin.HandlerFunc {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err})
return
}

info, err := tunnel.TunnelInfoForDevice(device.Properties.SerialNumber, ios.HttpApiPort())
if err == nil {
log.WithField("udid", device.Properties.SerialNumber).Printf("Received tunnel info %v", info)

device.UserspaceTUNPort = info.UserspaceTUNPort
device.UserspaceTUN = info.UserspaceTUN

device, err = deviceWithRsdProvider(device, udid, info.Address, info.RsdPort)
if err != nil {
c.Error(err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) // Return an error response
c.Next()
}
} else {
log.WithField("udid", device.Properties.SerialNumber).Warn("failed to get tunnel info")
}

c.Set(IOS_KEY, device)
c.Next()
}
}

func deviceWithRsdProvider(device ios.DeviceEntry, udid string, address string, rsdPort int) (ios.DeviceEntry, error) {
rsdService, err := ios.NewWithAddrPortDevice(address, rsdPort, device)
if err != nil {
return device, err
}

defer rsdService.Close()
rsdProvider, err := rsdService.Handshake()
if err != nil {
return device, err
}

device1, err := ios.GetDeviceWithAddress(udid, address, rsdProvider)
if err != nil {
return device, err
}

device1.UserspaceTUN = device.UserspaceTUN
device1.UserspaceTUNPort = device.UserspaceTUNPort

return device1, nil
}

const IOS_KEY = "go_ios_device"

// LimitNumClientsUDID limits clients to one concurrent connection per device UDID at a time
Expand Down
3 changes: 3 additions & 0 deletions restapi/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func simpleDeviceRoutes(device *gin.RouterGroup) {
device.PUT("/setlocation", SetLocation)
device.GET("/syslog", streamingMiddleWare, Syslog)

device.POST("/wda/session", CreateWdaSession)
device.GET("/wda/session/:sessionId", ReadWdaSession)
device.DELETE("/wda/session/:sessionId", DeleteWdaSession)
}

func appRoutes(group *gin.RouterGroup) {
Expand Down
Loading
Loading