screenshots

package
v1.260428.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ProviderAXe   = "axe"
	ProviderMacOS = "macos"
)

Variables

View Source
var (
	// ErrPlanRead indicates plan file read failure.
	ErrPlanRead = errors.New("read plan")
	// ErrPlanParseJSON indicates plan JSON decode failure.
	ErrPlanParseJSON = errors.New("parse plan JSON")
)

Functions

func FrameDeviceValues

func FrameDeviceValues() []string

FrameDeviceValues returns allowed --device values in CLI display order.

func IsCanvasDevice

func IsCanvasDevice(device FrameDevice) bool

IsCanvasDevice returns true if the device uses canvas mode (no device bezel).

func LoadApprovals added in v1.260404.0

func LoadApprovals(path string) (map[string]bool, error)

LoadApprovals reads approved review keys from disk.

func ResolveFrameDeviceFromConfig

func ResolveFrameDeviceFromConfig(configPath, fallback string) string

ResolveFrameDeviceFromConfig resolves the config device to a supported CLI slug.

func ResolveReviewOutputDir

func ResolveReviewOutputDir(outputDir string) (string, error)

ResolveReviewOutputDir resolves output dir with defaults and ensures absolute path.

func SaveApprovals

func SaveApprovals(path string, approvals map[string]bool) error

SaveApprovals writes approved keys to disk in a stable JSON format.

func WatchAndRegenerate

func WatchAndRegenerate(ctx context.Context, configPath string, debounce time.Duration, onCycle func(results []WatchCycleResult, err error), opts *WatchOptions) error

WatchAndRegenerate watches a Koubou YAML config file (and the raw asset directories it references) for changes, then re-runs kou generate on each change. It blocks until ctx is cancelled.

Types

type AXeProvider

type AXeProvider struct{}

AXeProvider captures a screenshot via the AXe CLI.

func (*AXeProvider) Capture

func (p *AXeProvider) Capture(ctx context.Context, req CaptureRequest) (string, error)

Capture launches the requested app and captures a screenshot via AXe.

type CanvasOptions

type CanvasOptions struct {
	Title         string
	Subtitle      string
	BGColor       string // solid background hex color (e.g. "#ffffff"); defaults to dark gradient
	TitleColor    string // title text color; defaults to canvasDefaultTitleColor
	SubtitleColor string // subtitle text color; defaults to canvasDefaultSubtitleColor
}

CanvasOptions controls title/subtitle/color overlays for canvas-mode devices (e.g. --device mac). All fields are optional; zero values use defaults.

type CaptureRequest

type CaptureRequest struct {
	Provider  string // ProviderAXe or ProviderMacOS
	BundleID  string
	UDID      string // simulator UDID or "booted"
	Name      string // output file name (without extension)
	OutputDir string // directory to write PNG
}

CaptureRequest holds parameters for a single screenshot capture.

type CaptureResult

type CaptureResult struct {
	Path     string `json:"path"`
	Provider string `json:"provider"`
	Width    int    `json:"width"`
	Height   int    `json:"height"`
	BundleID string `json:"bundle_id"`
	UDID     string `json:"udid"`
}

CaptureResult is the structured result of a successful capture.

func Capture

func Capture(ctx context.Context, req CaptureRequest) (*CaptureResult, error)

Capture runs the appropriate provider and validates the output file.

func CaptureWithProvider

func CaptureWithProvider(ctx context.Context, req CaptureRequest, p Provider) (*CaptureResult, error)

CaptureWithProvider runs the given provider (or selects by req.Provider if nil) and validates the output file. Used for testing with a mock provider.

type FrameDevice

type FrameDevice string

FrameDevice identifies a supported frame profile.

const (
	FrameDeviceIPhoneAir   FrameDevice = "iphone-air"
	FrameDeviceIPhone17Pro FrameDevice = "iphone-17-pro"
	FrameDeviceIPhone17PM  FrameDevice = "iphone-17-pro-max"
	FrameDeviceIPhone16e   FrameDevice = "iphone-16e"
	FrameDeviceIPhone17    FrameDevice = "iphone-17"
	FrameDeviceMac         FrameDevice = "mac"
)

func DefaultFrameDevice

func DefaultFrameDevice() FrameDevice

DefaultFrameDevice returns the default frame device.

func ParseFrameDevice

func ParseFrameDevice(raw string) (FrameDevice, error)

ParseFrameDevice normalizes and validates a frame device value.

type FrameDeviceOption

type FrameDeviceOption struct {
	ID      string `json:"id"`
	Default bool   `json:"default"`
}

FrameDeviceOption describes one supported frame device value.

func FrameDeviceOptions

func FrameDeviceOptions() []FrameDeviceOption

FrameDeviceOptions returns supported values with default marker.

type FrameRequest

type FrameRequest struct {
	InputPath  string         // required when ConfigPath is empty
	OutputPath string         // optional for custom config mode; required for input mode
	Device     string         // device slug; defaults to iphone-air when empty
	ConfigPath string         // optional Koubou YAML config path
	Canvas     *CanvasOptions // nil for bezel devices; non-nil for canvas devices (e.g. mac)

	// Kept for backwards compatibility; ignored in Koubou mode.
	FrameRoot   string
	ScreenBleed int
}

FrameRequest holds options for composing one screenshot.

type FrameResult

type FrameResult struct {
	Path         string `json:"path"`
	FramePath    string `json:"frame_path"`
	Device       string `json:"device"`
	DisplayType  string `json:"display_type,omitempty"`
	UploadWidth  int    `json:"upload_width,omitempty"`
	UploadHeight int    `json:"upload_height,omitempty"`
	Normalized   bool   `json:"normalized"`
	Width        int    `json:"width"`
	Height       int    `json:"height"`
}

FrameResult is the structured output for one composed frame image.

func Frame

func Frame(ctx context.Context, req FrameRequest) (*FrameResult, error)

Frame composes screenshots through Koubou's YAML pipeline.

type Plan

type Plan struct {
	Version  int          `json:"version"`
	App      PlanApp      `json:"app"`
	Defaults PlanDefaults `json:"defaults,omitempty"`
	Steps    []PlanStep   `json:"steps"`
}

Plan defines a deterministic screenshot automation sequence.

func LoadPlan

func LoadPlan(path string) (*Plan, error)

LoadPlan reads and validates a plan file.

func LoadPlanUnvalidated

func LoadPlanUnvalidated(path string) (*Plan, error)

LoadPlanUnvalidated reads and parses a plan file without validation.

type PlanApp

type PlanApp struct {
	BundleID  string `json:"bundle_id"`
	UDID      string `json:"udid,omitempty"`
	OutputDir string `json:"output_dir,omitempty"`
}

PlanApp contains app/simulator defaults for a run.

type PlanDefaults

type PlanDefaults struct {
	PostActionDelayMS int `json:"post_action_delay_ms,omitempty"`
}

PlanDefaults defines default timing behavior.

type PlanStep

type PlanStep struct {
	Action         StepAction `json:"action"`
	Name           *string    `json:"name,omitempty"`
	Label          *string    `json:"label,omitempty"`
	ID             *string    `json:"id,omitempty"`
	Contains       *string    `json:"contains,omitempty"`
	Text           *string    `json:"text,omitempty"`
	Keycodes       []int      `json:"keycodes,omitempty"`
	X              *float64   `json:"x,omitempty"`
	Y              *float64   `json:"y,omitempty"`
	DurationMS     *int       `json:"duration_ms,omitempty"`
	TimeoutMS      *int       `json:"timeout_ms,omitempty"`
	PollIntervalMS *int       `json:"poll_interval_ms,omitempty"`
}

PlanStep is one executable action in the plan.

type PlanValidationCode

type PlanValidationCode string

PlanValidationCode classifies validation failures.

const (
	PlanErrUnsupportedVersion PlanValidationCode = "unsupported_version"
	PlanErrMissingBundleID    PlanValidationCode = "missing_bundle_id"
	PlanErrMissingSteps       PlanValidationCode = "missing_steps"
	PlanErrNegativeDelay      PlanValidationCode = "negative_post_action_delay"
	PlanErrMissingAction      PlanValidationCode = "missing_action"
	PlanErrTapMissingTarget   PlanValidationCode = "tap_missing_target"
	PlanErrTypeMissingText    PlanValidationCode = "type_missing_text"
	PlanErrKeycodesMissing    PlanValidationCode = "keycodes_missing"
	PlanErrKeycodeInvalid     PlanValidationCode = "keycode_invalid"
	PlanErrWaitMissingMS      PlanValidationCode = "wait_missing_duration_ms"
	PlanErrWaitForMissingBy   PlanValidationCode = "wait_for_missing_matcher"
	PlanErrWaitForNegTimeout  PlanValidationCode = "wait_for_negative_timeout"
	PlanErrWaitForNegPoll     PlanValidationCode = "wait_for_negative_poll"
	PlanErrScreenshotNoName   PlanValidationCode = "screenshot_missing_name"
	PlanErrUnsupportedAction  PlanValidationCode = "unsupported_action"
)

type PlanValidationError

type PlanValidationError struct {
	Code    PlanValidationCode
	Step    int
	Message string
}

PlanValidationError describes a structured plan validation failure.

func (*PlanValidationError) Error

func (e *PlanValidationError) Error() string

type Provider

type Provider interface {
	Capture(ctx context.Context, req CaptureRequest) (pngPath string, err error)
}

Provider captures a single screenshot and returns the path to the PNG.

type ReviewApproveRequest

type ReviewApproveRequest struct {
	OutputDir    string
	ManifestPath string
	ApprovalPath string
	AllReady     bool
	Keys         []string
	ScreenshotID string
	Locale       string
	Device       string
}

ReviewApproveRequest configures updates to approved.json.

type ReviewApproveResult

type ReviewApproveResult struct {
	ManifestPath  string   `json:"manifest_path"`
	ApprovalPath  string   `json:"approval_path"`
	Matched       int      `json:"matched"`
	Added         int      `json:"added"`
	TotalApproved int      `json:"total_approved"`
	Keys          []string `json:"keys,omitempty"`
}

ReviewApproveResult summarizes approval updates.

func ApproveReview

func ApproveReview(ctx context.Context, req ReviewApproveRequest) (*ReviewApproveResult, error)

ApproveReview writes/updates approval keys for review entries.

type ReviewEntry

type ReviewEntry struct {
	Key               string   `json:"key"`
	ScreenshotID      string   `json:"screenshot_id"`
	Locale            string   `json:"locale,omitempty"`
	Device            string   `json:"device,omitempty"`
	FramedPath        string   `json:"framed_path"`
	FramedRelative    string   `json:"framed_relative_path"`
	RawPath           string   `json:"raw_path,omitempty"`
	RawRelative       string   `json:"raw_relative_path,omitempty"`
	Width             int      `json:"width"`
	Height            int      `json:"height"`
	DisplayTypes      []string `json:"display_types,omitempty"`
	ValidAppStoreSize bool     `json:"valid_app_store_size"`
	Status            string   `json:"status"`
	Approved          bool     `json:"approved"`
	ApprovalState     string   `json:"approval_state"`
}

ReviewEntry represents one framed screenshot row in review artifacts.

type ReviewManifest

type ReviewManifest struct {
	GeneratedAt  string        `json:"generated_at"`
	RawDir       string        `json:"raw_dir,omitempty"`
	FramedDir    string        `json:"framed_dir"`
	OutputDir    string        `json:"output_dir"`
	ApprovalPath string        `json:"approval_path"`
	Summary      ReviewSummary `json:"summary"`
	Entries      []ReviewEntry `json:"entries"`
}

ReviewManifest is the JSON artifact for agent/human checks.

func LoadReviewManifest

func LoadReviewManifest(path string) (*ReviewManifest, error)

LoadReviewManifest parses a generated review manifest from disk.

type ReviewOpenRequest

type ReviewOpenRequest struct {
	OutputDir string
	HTMLPath  string
	DryRun    bool
}

ReviewOpenRequest configures opening a generated review HTML file.

type ReviewOpenResult

type ReviewOpenResult struct {
	HTMLPath string `json:"html_path"`
	Opened   bool   `json:"opened"`
}

ReviewOpenResult describes the resolved review HTML path and open state.

func OpenReview

func OpenReview(ctx context.Context, req ReviewOpenRequest) (*ReviewOpenResult, error)

OpenReview opens the generated review HTML in the default browser.

type ReviewRequest

type ReviewRequest struct {
	RawDir       string // optional; missing raw files are reported
	FramedDir    string // required
	OutputDir    string // optional, defaults to ./screenshots/review
	ApprovalPath string // optional, defaults to <output-dir>/approved.json
}

ReviewRequest configures generation of screenshot review artifacts.

type ReviewResult

type ReviewResult struct {
	ManifestPath string `json:"manifest_path"`
	HTMLPath     string `json:"html_path"`
	ApprovalPath string `json:"approval_path"`
	FramedDir    string `json:"framed_dir"`
	Total        int    `json:"total"`
	Ready        int    `json:"ready"`
	MissingRaw   int    `json:"missing_raw"`
	InvalidSize  int    `json:"invalid_size"`
	Approved     int    `json:"approved"`
	Pending      int    `json:"pending"`
}

ReviewResult is printed by CLI after artifacts are written.

func GenerateReview

func GenerateReview(ctx context.Context, req ReviewRequest) (*ReviewResult, error)

GenerateReview creates manifest and HTML side-by-side report artifacts.

type ReviewSummary

type ReviewSummary struct {
	Total           int `json:"total"`
	Ready           int `json:"ready"`
	MissingRaw      int `json:"missing_raw"`
	InvalidSize     int `json:"invalid_size"`
	Approved        int `json:"approved"`
	PendingApproval int `json:"pending_approval"`
}

ReviewSummary aggregates status/approval totals across all entries.

type RunResult

type RunResult struct {
	BundleID  string          `json:"bundle_id"`
	UDID      string          `json:"udid"`
	OutputDir string          `json:"output_dir"`
	Steps     []RunStepResult `json:"steps"`
}

RunResult is the structured output for a plan run.

func RunPlan

func RunPlan(ctx context.Context, plan *Plan) (*RunResult, error)

RunPlan executes a validated plan.

type RunStepResult

type RunStepResult struct {
	Index      int    `json:"index"`
	Action     string `json:"action"`
	Status     string `json:"status"`
	DurationMS int64  `json:"duration_ms"`
	Error      string `json:"error,omitempty"`
}

RunStepResult reports one executed step.

type StepAction

type StepAction string

StepAction is one supported automation step.

const (
	ActionLaunch      StepAction = "launch"
	ActionTap         StepAction = "tap"
	ActionType        StepAction = "type"
	ActionKeySequence StepAction = "key_sequence"
	ActionWait        StepAction = "wait"
	ActionWaitFor     StepAction = "wait_for"
	ActionScreenshot  StepAction = "screenshot"
)

type WatchCycleResult

type WatchCycleResult struct {
	Name    string `json:"name"`
	Path    string `json:"path"`
	Success bool   `json:"success"`
	Error   string `json:"error,omitempty"`
}

WatchCycleResult describes one screenshot generated per watch cycle.

type WatchOptions

type WatchOptions struct {
	// ReviewOutputDir, when non-empty, triggers automatic review HTML/manifest
	// regeneration after each successful kou generate cycle.
	ReviewOutputDir string
	// ReviewRawDir is the raw screenshots directory for review generation.
	ReviewRawDir string
}

WatchOptions configures optional review regeneration after each watch cycle.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL