diff --git a/cmd/sanderling/main.go b/cmd/sanderling/main.go index 8273656..ed7cc36 100644 --- a/cmd/sanderling/main.go +++ b/cmd/sanderling/main.go @@ -16,15 +16,16 @@ import ( var Version = "dev" type testOptions struct { - spec string - bundleID string - platform string - avd string - iosDevice string - duration time.Duration - seed int64 - output string - clearData bool + spec string + bundleID string + platform string + avd string + iosDevice string + iosAppPath string + duration time.Duration + seed int64 + output string + clearData bool } const topUsage = `sanderling is a property-based UI fuzzer for mobile apps. @@ -50,6 +51,7 @@ func parseTestArgs(args []string, stderr io.Writer) (testOptions, error) { flagSet.StringVar(&options.platform, "platform", "android", "target platform: android, ios, web") flagSet.StringVar(&options.avd, "avd", "", "Android AVD name to boot if no device is connected") flagSet.StringVar(&options.iosDevice, "ios-device", "", "iOS simulator name or UDID to boot if none is running") + flagSet.StringVar(&options.iosAppPath, "ios-app-path", "", "path to the .app bundle for iOS simulator clear-state reinstall") flagSet.DurationVar(&options.duration, "duration", 5*time.Minute, "total test duration") flagSet.Int64Var(&options.seed, "seed", 0, "RNG seed (0 = random)") flagSet.StringVar(&options.output, "output", "./runs", "output directory for traces") diff --git a/cmd/sanderling/main_test.go b/cmd/sanderling/main_test.go index 2cb99a5..fa9ebc0 100644 --- a/cmd/sanderling/main_test.go +++ b/cmd/sanderling/main_test.go @@ -181,6 +181,31 @@ func TestParseTestArgs_IosDeviceFlag(t *testing.T) { } } +func TestParseTestArgs_IosAppPathFlag(t *testing.T) { + options, err := parseTestArgs([]string{ + "--spec", "s.ts", + "--bundle-id", "com.example.app", + "--platform", "ios", + "--ios-app-path", "/tmp/build/iosApp.app", + }, io.Discard) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if options.iosAppPath != "/tmp/build/iosApp.app" { + t.Errorf("expected iosAppPath=/tmp/build/iosApp.app, got %q", options.iosAppPath) + } +} + +func TestParseTestArgs_IosAppPathOptional(t *testing.T) { + options, err := parseTestArgs([]string{"--spec", "s.ts", "--bundle-id", "com.example.app"}, io.Discard) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if options.iosAppPath != "" { + t.Errorf("iosAppPath default: got %q, want empty", options.iosAppPath) + } +} + func TestRun_TestSubcommand_PipelineErrors(t *testing.T) { // Web skips host-dependent device boot and bundles first, so a missing spec // deterministically surfaces a bundle-resolution error. This proves the diff --git a/cmd/sanderling/test_run.go b/cmd/sanderling/test_run.go index 96d32e1..f8407d1 100644 --- a/cmd/sanderling/test_run.go +++ b/cmd/sanderling/test_run.go @@ -9,14 +9,15 @@ import ( func runTestPipeline(ctx context.Context, options testOptions, stdout io.Writer) error { return testrun.Execute(ctx, testrun.Options{ - Spec: options.spec, - BundleID: options.bundleID, - Platform: options.platform, - AVD: options.avd, - IosDevice: options.iosDevice, - Duration: options.duration, - Seed: options.seed, - Output: options.output, - ClearData: options.clearData, + Spec: options.spec, + BundleID: options.bundleID, + Platform: options.platform, + AVD: options.avd, + IosDevice: options.iosDevice, + IosAppPath: options.iosAppPath, + Duration: options.duration, + Seed: options.seed, + Output: options.output, + ClearData: options.clearData, }, stdout) }