Documentation
¶
Overview ¶
Package ios is the host-side client for the iOS XCTest runner's HTTP API.
contracts/v0/ios-http.json is the contract: eighteen routes on a loopback server, their exact JSON shapes, and the mapping from HTTP status to error code. Nothing here talks to a simulator; the client is pure transport and is testable with an HTTP server without a simulator.
Index ¶
- Constants
- func DeclaredCapabilities() device.Capabilities
- func DefaultBaseURL(port int) string
- type AXElement
- type Button
- type Client
- func (client *Client) DeviceInfo(ctx context.Context) (DeviceInfo, error)
- func (client *Client) EraseText(ctx context.Context, characters int, appIDs []string) error
- func (client *Client) Identity(ctx context.Context) (string, error)
- func (client *Client) InputText(ctx context.Context, text string, appIDs []string) error
- func (client *Client) IsScreenStatic(ctx context.Context) (bool, error)
- func (client *Client) KeyboardVisible(ctx context.Context, appIDs []string) (bool, error)
- func (client *Client) LaunchApp(ctx context.Context, bundleID string) error
- func (client *Client) PressButton(ctx context.Context, button Button) error
- func (client *Client) PressKey(ctx context.Context, key Key, appIDs []string) error
- func (client *Client) RunningApp(ctx context.Context, appIDs []string) (string, error)
- func (client *Client) Screenshot(ctx context.Context, compressed bool) ([]byte, error)
- func (client *Client) SetOrientation(ctx context.Context, orientation Orientation) error
- func (client *Client) SetPermissions(ctx context.Context, permissions map[string]string) error
- func (client *Client) SetTransportHint(hint func() string)
- func (client *Client) Status(ctx context.Context) error
- func (client *Client) Swipe(ctx context.Context, request SwipeRequest) error
- func (client *Client) SwipeV2(ctx context.Context, request SwipeV2Request) error
- func (client *Client) TerminateApp(ctx context.Context, appID string) error
- func (client *Client) Touch(ctx context.Context, request TouchRequest) error
- func (client *Client) ViewHierarchy(ctx context.Context, appIDs []string, excludeKeyboardElements bool) (ViewHierarchy, error)
- type Code
- type CommandRunner
- type Device
- type DeviceInfo
- type DeviceTools
- type Driver
- func (driver *Driver) AddMedia(ctx context.Context, request device.AddMediaRequest) error
- func (driver *Driver) BackPress(context.Context) error
- func (driver *Driver) Capabilities() device.Capabilities
- func (driver *Driver) ClearAppState(ctx context.Context, request device.AppRequest) error
- func (driver *Driver) ClearKeychain(ctx context.Context) error
- func (driver *Driver) Close(ctx context.Context) error
- func (driver *Driver) CollectCrashArtifacts(ctx context.Context, request device.ArtifactRequest) ([]device.Artifact, error)
- func (driver *Driver) ContentDescriptor(ctx context.Context, request device.ContentDescriptorRequest) (device.TreeNode, error)
- func (driver *Driver) CurrentOrientation(ctx context.Context) (device.Orientation, error)
- func (driver *Driver) DeviceInfo(ctx context.Context) (device.DeviceInfo, error)
- func (driver *Driver) EraseText(ctx context.Context, request device.EraseTextRequest) error
- func (driver *Driver) HideKeyboard(ctx context.Context) error
- func (driver *Driver) InputText(ctx context.Context, request device.InputTextRequest) error
- func (driver *Driver) IsAirplaneModeEnabled(context.Context) (bool, error)
- func (driver *Driver) IsKeyboardVisible(ctx context.Context, request device.KeyboardRequest) (bool, error)
- func (driver *Driver) IsShutdown(ctx context.Context) (bool, error)
- func (driver *Driver) KillApp(ctx context.Context, request device.AppRequest) error
- func (driver *Driver) LaunchApp(ctx context.Context, request device.LaunchAppRequest) error
- func (driver *Driver) LongPress(ctx context.Context, request device.LongPressRequest) error
- func (driver *Driver) Name() string
- func (driver *Driver) Open(ctx context.Context) error
- func (driver *Driver) OpenLink(ctx context.Context, request device.OpenLinkRequest) error
- func (driver *Driver) PressKey(ctx context.Context, request device.PressKeyRequest) error
- func (driver *Driver) QueryOnDeviceElements(context.Context, device.QueryRequest) ([]device.TreeNode, error)
- func (driver *Driver) ResetProxy(context.Context) error
- func (driver *Driver) ScrollVertical(ctx context.Context, request device.ScrollVerticalRequest) error
- func (driver *Driver) SetAirplaneMode(context.Context, device.AirplaneModeRequest) error
- func (driver *Driver) SetAndroidChromeDevToolsEnabled(context.Context, device.ChromeDevToolsRequest) error
- func (driver *Driver) SetLocation(ctx context.Context, location device.Location) error
- func (driver *Driver) SetOrientation(ctx context.Context, orientation device.Orientation) error
- func (driver *Driver) SetPermissions(ctx context.Context, request device.PermissionsRequest) error
- func (driver *Driver) SetProxy(context.Context, device.Proxy) error
- func (driver *Driver) StartDeviceLogCapture(ctx context.Context, request device.DeviceLogRequest) (device.CaptureID, error)
- func (driver *Driver) StartScreenRecording(ctx context.Context, request device.ScreenRecordingRequest) (device.CaptureID, error)
- func (driver *Driver) StopApp(ctx context.Context, request device.AppRequest) error
- func (driver *Driver) StopDeviceLogCapture(ctx context.Context, id device.CaptureID) ([]device.Artifact, error)
- func (driver *Driver) StopScreenRecording(ctx context.Context, id device.CaptureID) ([]device.Artifact, error)
- func (driver *Driver) Swipe(ctx context.Context, request device.SwipeRequest) error
- func (driver *Driver) TakeScreenshot(ctx context.Context, request device.ScreenshotRequest) ([]byte, error)
- func (driver *Driver) Tap(ctx context.Context, request device.TapRequest) error
- func (driver *Driver) WaitForAppToSettle(ctx context.Context, request device.SettleRequest) (*device.ViewHierarchy, error)
- func (driver *Driver) WaitUntilScreenIsStatic(ctx context.Context, _ device.ScreenStaticRequest) (bool, error)
- type Error
- type ExecRunner
- type Frame
- type Key
- type LaunchArgument
- type Option
- type Orientation
- type RunnerBundle
- type ScreenOrientation
- type Simctl
- func (simctl *Simctl) AddMedia(ctx context.Context, paths []string) error
- func (simctl *Simctl) AppContainer(ctx context.Context, bundleID string) (string, error)
- func (simctl *Simctl) Boot(ctx context.Context) error
- func (simctl *Simctl) Diagnose(ctx context.Context, outputDirectory string, timeout time.Duration) error
- func (simctl *Simctl) Install(ctx context.Context, appPath string) error
- func (simctl *Simctl) Launch(ctx context.Context, bundleID string, arguments []LaunchArgument, ...) error
- func (simctl *Simctl) ListDevices(ctx context.Context) ([]Device, error)
- func (simctl *Simctl) OpenURL(ctx context.Context, url string) error
- func (simctl *Simctl) ResetKeychain(ctx context.Context) error
- func (simctl *Simctl) Screenshot(ctx context.Context, outputPath string) error
- func (simctl *Simctl) SetLocation(ctx context.Context, latitude, longitude float64) error
- func (simctl *Simctl) SetPermission(ctx context.Context, bundleID, permission, grant string) error
- func (simctl *Simctl) Shutdown(ctx context.Context) error
- func (simctl *Simctl) Terminate(ctx context.Context, bundleID string) error
- func (simctl *Simctl) Uninstall(ctx context.Context, bundleID string) error
- type SwipeRequest
- type SwipeV2Request
- type TouchRequest
- type ViewHierarchy
Constants ¶
const DefaultPort = 22087
DefaultPort is the runner's default loopback port, frozen by the contract's transport block.
const Platform = device.Platform("ios")
Platform is the device platform this driver reports.
Variables ¶
This section is empty.
Functions ¶
func DeclaredCapabilities ¶
func DeclaredCapabilities() device.Capabilities
DeclaredCapabilities is the non-mutating iOS Simulator capability document used by both the driver and selected-platform flow preflight.
func DefaultBaseURL ¶
DefaultBaseURL renders the contract's loopback address for a port.
Types ¶
type AXElement ¶
type AXElement struct {
Identifier string `json:"identifier"`
Frame Frame `json:"frame"`
Value *string `json:"value,omitempty"`
Title *string `json:"title,omitempty"`
Label string `json:"label"`
ElementType int `json:"elementType"`
Enabled bool `json:"enabled"`
HorizontalSizeClass int `json:"horizontalSizeClass"`
VerticalSizeClass int `json:"verticalSizeClass"`
PlaceholderValue *string `json:"placeholderValue,omitempty"`
Selected bool `json:"selected"`
HasFocus bool `json:"hasFocus"`
Children []AXElement `json:"children,omitempty"`
WindowContextID float64 `json:"windowContextID"`
DisplayID int `json:"displayID"`
}
AXElement is one node of the runner's accessibility hierarchy.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client speaks the frozen runner API.
func (*Client) DeviceInfo ¶
func (client *Client) DeviceInfo(ctx context.Context) (DeviceInfo, error)
func (*Client) Identity ¶
Identity is the health check that also answers who is serving: the runner echoes the id the host launched it with, so a driver that started a runner can tell its own child from a stranger holding the same port. A healthy runner launched without an id answers "".
func (*Client) IsScreenStatic ¶
func (*Client) KeyboardVisible ¶
func (*Client) PressButton ¶
func (*Client) RunningApp ¶
func (*Client) Screenshot ¶
Screenshot returns the raw image bytes: JPEG when compressed, PNG otherwise.
func (*Client) SetOrientation ¶
func (client *Client) SetOrientation(ctx context.Context, orientation Orientation) error
func (*Client) SetPermissions ¶
func (*Client) SetTransportHint ¶
SetTransportHint installs the explanation to attach when the runner cannot be reached at all. Only the owner of the runner process can supply it, which is why it arrives after construction rather than as an Option.
func (*Client) Status ¶
Status is the health check. A 200 carrying anything other than "ok" is not a healthy runner, and reporting it as one would be worse than an error.
func (*Client) SwipeV2 ¶
func (client *Client) SwipeV2(ctx context.Context, request SwipeV2Request) error
func (*Client) TerminateApp ¶
func (*Client) ViewHierarchy ¶
type CommandRunner ¶
type CommandRunner interface {
Run(ctx context.Context, name string, args ...string) ([]byte, error)
}
CommandRunner executes one external command and returns its combined output.
type DeviceInfo ¶
type DeviceInfo struct {
WidthPoints float64 `json:"widthPoints"`
HeightPoints float64 `json:"heightPoints"`
WidthPixels float64 `json:"widthPixels"`
HeightPixels float64 `json:"heightPixels"`
Orientation ScreenOrientation `json:"orientation"`
}
DeviceInfo is the runner's screen geometry, in points and pixels.
type DeviceTools ¶
type DeviceTools interface {
Launch(ctx context.Context, bundleID string, arguments []LaunchArgument, terminateRunning bool) error
Terminate(ctx context.Context, bundleID string) error
Uninstall(ctx context.Context, bundleID string) error
AppContainer(ctx context.Context, bundleID string) (string, error)
Install(ctx context.Context, appPath string) error
Diagnose(ctx context.Context, outputDirectory string, timeout time.Duration) error
ResetKeychain(ctx context.Context) error
OpenURL(ctx context.Context, url string) error
SetLocation(ctx context.Context, latitude, longitude float64) error
AddMedia(ctx context.Context, paths []string) error
SetPermission(ctx context.Context, bundleID, permission, grant string) error
}
DeviceTools is the out-of-app half of the driver: everything it does to the device from outside the runner's wire. The simulator implementation is Simctl; a physical device supplies its own implementation, and the Driver cannot tell them apart. The in-app half stays on Client.
type Driver ¶
type Driver struct {
// contains filtered or unexported fields
}
Driver drives one simulator.
func NewDriver ¶
func NewDriver( udid string, port int, client *Client, simctl DeviceTools, runner *RunnerBundle, ) *Driver
NewDriver binds a runner client and a device-tools surface to one udid. The simulator passes Simctl; a physical device passes its own DeviceTools.
func (*Driver) Capabilities ¶
func (driver *Driver) Capabilities() device.Capabilities
Capabilities declares what this driver refuses. Every false here has a matching ErrUnsupported at call time; preflight reads this so a flow is refused before it runs rather than halfway through.
func (*Driver) ClearAppState ¶
ClearAppState preserves the installed application bundle, uninstalls it to clear its data container, then reinstalls the same bundle. The engine applies permissions and launches only after this call succeeds.
func (*Driver) Close ¶
Close stops a runner this driver started and leaves the simulator as it was. Shutting the simulator down would destroy the state an operator may want to inspect after a failed run, and the session that booted it is the one that should decide its fate. An operator-started runner is left alone for the same reason.
func (*Driver) CollectCrashArtifacts ¶
func (*Driver) ContentDescriptor ¶
func (*Driver) CurrentOrientation ¶
func (*Driver) DeviceInfo ¶
func (*Driver) HideKeyboard ¶
HideKeyboard has no route of its own. The keyboard dismisses on return, which is the gesture a person would use.
The press is skipped when no keyboard is up, and not only to save a round trip: the runner refuses to type when nothing on screen accepts text, so asking it to press Return on a screen without a keyboard turns a keyboard that is already hidden into a failed command.
func (*Driver) IsAirplaneModeEnabled ¶
func (*Driver) IsKeyboardVisible ¶
func (*Driver) IsShutdown ¶
IsShutdown asks the runner, not simctl. A booted simulator whose runner has died is unusable for a flow even though simctl still calls it Booted.
func (*Driver) KillApp ¶
KillApp is StopApp on iOS. A simulator has no distinction between a graceful stop and a kill: simctl terminate is the only verb, and inventing a difference would mean one of the two silently does the other's job.
func (*Driver) LaunchApp ¶
LaunchApp goes through simctl, not the runner: only simctl can carry the typed launch arguments, and the runner's route would drop them silently.
func (*Driver) LongPress ¶
LongPress sends the same route with a duration. TouchRequest.Duration is a pointer because its presence is what makes the touch a long press, so a tap must not send a zero.
func (*Driver) Name ¶
Name identifies the runner this driver talks to, port included. Each shard has its own port, so the pair identifies the runner in operator messages.
func (*Driver) Open ¶
Open confirms the runner is answering so absence is reported as a setup failure. With a bundle it owns the runner's whole life: start it, then poll until it answers. See managed_runner.go.
func (*Driver) OpenLink ¶
OpenLink hands the URL to the simulator, which opens it in the system default. A browser choice cannot be honored, and honoring it silently in the wrong browser would be worse than refusing.
func (*Driver) QueryOnDeviceElements ¶
func (driver *Driver) QueryOnDeviceElements( context.Context, device.QueryRequest, ) ([]device.TreeNode, error)
QueryOnDeviceElements has no route in the frozen contract. The runner returns a whole hierarchy; it does not evaluate queries against it.
func (*Driver) ScrollVertical ¶
func (driver *Driver) ScrollVertical(ctx context.Context, request device.ScrollVerticalRequest) error
ScrollVertical is a swipe across the middle of the screen. The runner has no scroll route, so the distance comes from the device's own geometry rather than a guessed constant.
func (*Driver) SetAirplaneMode ¶
func (*Driver) SetAndroidChromeDevToolsEnabled ¶
func (*Driver) SetLocation ¶
func (*Driver) SetOrientation ¶
func (*Driver) SetPermissions ¶
SetPermissions issues one simctl call per permission. simctl takes a single service per invocation, and map order must not decide what gets applied first — a permission change can terminate the app, so the order is observable.
func (*Driver) StartDeviceLogCapture ¶
func (*Driver) StartScreenRecording ¶
func (driver *Driver) StartScreenRecording( ctx context.Context, request device.ScreenRecordingRequest, ) (device.CaptureID, error)
StartScreenRecording spawns `xcrun simctl io <udid> recordVideo <sink>` as a long-lived child (specs/02-device-drivers.md line 9) and returns a CaptureID that StopScreenRecording later stops. simctl writes straight to the sink and finalizes the .mov on SIGINT, so the sink is the artifact once stop returns.
func (*Driver) StopDeviceLogCapture ¶
func (*Driver) StopScreenRecording ¶
func (driver *Driver) StopScreenRecording( ctx context.Context, id device.CaptureID, ) ([]device.Artifact, error)
StopScreenRecording ends a recording StartScreenRecording began and returns the artifact at its sink. It is deliberately NOT on the frozen Driver surface — v0 declares only the start half — so the recording controller completes the lifecycle by calling this concrete method directly.
func (*Driver) Swipe ¶
Swipe covers all three shapes specs/02-device-drivers.md §1 gives the driver: explicit points, a bare direction, and an element point plus a direction.
Direction-only swipes resolve screen geometry through the device before calculating their endpoints.
func (*Driver) TakeScreenshot ¶
func (*Driver) WaitForAppToSettle ¶
func (driver *Driver) WaitForAppToSettle( ctx context.Context, request device.SettleRequest, ) (*device.ViewHierarchy, error)
WaitForAppToSettle returns nil when settling cannot be confirmed. Callers must not interpret nil as settled confirmation.
func (*Driver) WaitUntilScreenIsStatic ¶
type Error ¶
Error is a runner-reported failure. The body's code is authoritative; the status mapping is the fallback for a runner that answers without one.
type Frame ¶
type Frame struct {
X float64 `json:"X"`
Y float64 `json:"Y"`
Width float64 `json:"Width"`
Height float64 `json:"Height"`
}
Frame is an element's screen-space rectangle.
type LaunchArgument ¶
LaunchArgument is one typed launch argument. Type uses the public documentation's vocabulary: string, boolean, integer, double.
type Option ¶
type Option func(*Client)
Option customizes a client at construction.
func WithHTTPClient ¶
WithHTTPClient replaces the underlying HTTP client, for callers that need their own transport or timeout.
type Orientation ¶
type Orientation string
Orientation is the setOrientation vocabulary.
const ( OrientationPortrait Orientation = "portrait" OrientationLandscapeLeft Orientation = "landscapeLeft" OrientationLandscapeRight Orientation = "landscapeRight" OrientationUpsideDown Orientation = "upsideDown" )
type RunnerBundle ¶
type RunnerBundle struct {
XCTestRun string
}
RunnerBundle names a prebuilt runner the driver may start itself. A nil bundle selects operator-started mode, where the runner must already serve.
XCTestRun is the .xctestrun `xcodebuild build-for-testing` leaves in the derived-data products directory. It is the whole reason a self-starting runner is possible: `test-without-building -xctestrun <path>` needs no Xcode project at run time, only the built products the file points at.
type ScreenOrientation ¶
type ScreenOrientation string
ScreenOrientation is the deviceInfo orientation vocabulary.
const ( ScreenOrientationPortrait ScreenOrientation = "portrait" ScreenOrientationUpsideDown ScreenOrientation = "portrait-upside-down" ScreenOrientationLandscapeLeft ScreenOrientation = "landscape-left" ScreenOrientationLandscapeRight ScreenOrientation = "landscape-right" )
type Simctl ¶
type Simctl struct {
// contains filtered or unexported fields
}
Simctl is the typed surface over `xcrun simctl` for one simulator.
func NewSimctl ¶
func NewSimctl(udid string, runner CommandRunner) *Simctl
NewSimctl binds a udid to a runner. An empty udid is legal only for the commands that are not device-scoped, such as ListDevices.
func (*Simctl) AppContainer ¶
AppContainer returns the installed .app bundle path, not its data container. ClearAppState preserves that bundle before uninstalling the application.
func (*Simctl) Diagnose ¶
func (simctl *Simctl) Diagnose(ctx context.Context, outputDirectory string, timeout time.Duration) error
Diagnose collects a device-scoped archive without opening Finder. Both the host context and simctl's own timeout bound collection.
func (*Simctl) Launch ¶
func (simctl *Simctl) Launch( ctx context.Context, bundleID string, arguments []LaunchArgument, terminateRunning bool, ) error
Launch starts an app. terminateRunning maps onto simctl's own --terminate-running-process, which is how stopApp is expressed here.
func (*Simctl) ListDevices ¶
ListDevices returns every available simulator across runtimes. Unavailable entries are dropped: they cannot be booted, so offering them as targets would only produce a later failure.
func (*Simctl) ResetKeychain ¶
ResetKeychain clears the whole simulator keychain, which is what clearKeychain means on iOS.
func (*Simctl) Screenshot ¶
func (*Simctl) SetLocation ¶
SetLocation sets the simulated location. simctl takes one "lat,lon" argument, and the numbers are rendered without an exponent so a coordinate never reaches the device in a form it cannot parse.
func (*Simctl) SetPermission ¶
SetPermission maps the authored grant onto simctl's privacy verbs. The grant set is the same exact three the engine validates, so an unknown one is refused here rather than passed to the device as a stray verb.
type SwipeRequest ¶
type SwipeRequest struct {
AppID string `json:"appId,omitempty"`
StartX float64 `json:"startX"`
StartY float64 `json:"startY"`
EndX float64 `json:"endX"`
EndY float64 `json:"endY"`
Duration float64 `json:"duration"`
}
SwipeRequest is the v1 swipe, which carries a single optional appId.
type SwipeV2Request ¶
type SwipeV2Request struct {
StartX float64 `json:"startX"`
StartY float64 `json:"startY"`
EndX float64 `json:"endX"`
EndY float64 `json:"endY"`
Duration float64 `json:"duration"`
AppIDs []string `json:"appIds,omitempty"`
}
SwipeV2Request is the orientation-aware swipe, which carries an appId list.
type TouchRequest ¶
type TouchRequest struct {
X float64 `json:"x"`
Y float64 `json:"y"`
Duration *float64 `json:"duration,omitempty"`
}
TouchRequest taps at a point. Duration is a pointer because its presence is what turns the touch into a long press, so an absent one must not be sent as a zero.
type ViewHierarchy ¶
ViewHierarchy is the runner's hierarchy response.