import AppKit import TerebiConfiguration @MainActor private final class FixedQualityClock { var now = 1000.0 } @main @MainActor struct AutomaticQualityPlaybackChecks { static func require(_ condition: @autoclosure () -> Bool, _ message: String) { if !condition() { FileHandle.standardError.write(Data(("FAIL: " + message + "\n").utf8)) exit(1) } } // Only the infrastructure watchdog uses elapsed time. Adaptation uses an injected clock; // playback readiness and network stalls are observable media events, not sleeps. static func until(_ model: PlayerModel, _ message: String, _ condition: () -> Bool) { let deadline = ContinuousClock.now.advanced(by: .seconds(20)) while !condition(), ContinuousClock.now < deadline { RunLoop.main.run(until: Date(timeIntervalSinceNow: 0.01)) } require(condition(), message + " (height=\(model.youtubeHeight ?? 0), status=\(model.state.status), error=\(model.errorText ?? "none"))") } static func polled(_ model: PlayerModel) { let revision = model.state.revision until(model, "native model processes a fresh playback snapshot") { model.state.revision != revision } } static func main() { _ = NSApplication.shared NSApp.setActivationPolicy(.prohibited) let suite = "terebi.automatic-quality-playback-check.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suite)! defer { defaults.removePersistentDomain(forName: suite) } let clock = FixedQualityClock() let model = PlayerModel(defaults: defaults, qualityClock: { clock.now }) defer { model.shutdown() } model.setVolume(0) require(!model.automaticYouTubeQuality, "automatic quality is opt-in") model.openYouTube("https://www.youtube.com/watch?v=aqz-KE-bpKQ") until(model, "default selects real 1080p and runs out of the gated network prefix") { model.youtubeHeight == 1080 && model.canTogglePlayback && model.state.status == PLAYER_PLAYING && model.state.position > 0.5 && model.state.buffering } clock.now = 2000 polled(model) require(model.youtubeHeight == 1080 && !model.resolvingYouTube, "disabled automatic quality leaves a stalled manual/default stream alone") model.setAutomaticYouTubeQuality(true) polled(model) let position = model.state.position clock.now = 2003 until(model, "persistent stall automatically reopens actual 720p media") { model.youtubeHeight == 720 && model.canTogglePlayback && model.state.status == PLAYER_PLAYING && !model.state.seek_pending && (model.bufferedRange.map { $0.upperBound - model.state.position >= 20 } ?? false) } require(model.state.position >= position && model.state.position < position + 3, "automatic quality reopening preserves current playback progress") polled(model) clock.now = 2063 until(model, "sustained health automatically restores actual 1080p media") { model.youtubeHeight == 1080 && model.canTogglePlayback && model.state.status == PLAYER_PLAYING && !model.state.seek_pending } model.setYouTubeQuality(model.youtubeHeight) require(!model.automaticYouTubeQuality && !model.isBusy && model.state.status == PLAYER_PLAYING, "reselecting the current manual resolution disables auto without disrupting playback") model.setAutomaticYouTubeQuality(true) let reopened = PlayerModel(defaults: defaults, qualityClock: { clock.now }) require(!reopened.automaticYouTubeQuality, "session opt-in does not survive player restart") reopened.shutdown() model.setYouTubeQuality(nil) require(!model.automaticYouTubeQuality && model.youtubeQuality == nil, "default quality is also a manual override") let manual = PlayerModel(defaults: defaults, configuration: PlayerConfiguration(automaticQuality: true), qualityClock: { clock.now }) require(manual.automaticYouTubeQuality, "manual session override does not replace startup configuration") manual.shutdown() model.closeFile() print("PASS native adaptive playback: default-off/stalled downshift/healthy upshift/progress preservation/current+default manual override/session-only settings") } }