-- | End-to-end TUISpec coverage for @tui-launcher@.
module Main (main) where
import Data.Text qualified as T
import Data.Text.IO qualified as TIO
import System.Directory (
createDirectoryIfMissing,
findExecutable,
getTemporaryDirectory,
)
import System.FilePath ((</>))
import Test.Tasty (TestTree, defaultMain, testGroup)
import TuiSpec
-- | Run the TUISpec test suite.
main :: IO ()
main = defaultMain tests
-- | Full test tree.
tests :: TestTree
tests =
testGroup
"tui-launcher"
[launchesShellEntryFromExplicitConfig]
{- | Verify that @--config@ loads explicit entries, arrow-key navigation moves
selection, and choosing the @Shell@ entry drops into a real shell.
-}
launchesShellEntryFromExplicitConfig :: TestTree
launchesShellEntryFromExplicitConfig =
tuiTest runOptions "launches shell from --config with arrow keys" $ \tui -> do
(binaryPath, configPath) <- prepareConfig "tui-launcher-launch" launcherConfig
launch tui (app binaryPath ["--config", configPath])
waitForText tui (Nth 0 (Exact "tui-launcher"))
waitForText tui (Nth 0 (Exact "Logs"))
waitForText tui (Nth 0 (Exact "InteractiveShell"))
waitForText tui (Nth 0 (Exact "Exit"))
press tui ArrowRight
press tui Enter
sendLine tui "echo 'hello, world'"
waitForText tui (Nth 0 (Exact "hello, world"))
sendLine tui "exit"
-- | Shared TUISpec runtime options for integration tests.
runOptions :: RunOptions
runOptions =
defaultRunOptions
{ timeoutSeconds = 15
, terminalCols = 80
, terminalRows = 24
, artifactsDir = "artifacts/tui-launcher-smoke"
}
{- | Write a config file for a test and return the launcher binary plus config
path.
-}
prepareConfig :: FilePath -> T.Text -> IO (FilePath, FilePath)
prepareConfig testName configText = do
tempDir <- getTemporaryDirectory
let configDir = tempDir </> testName
configPath = configDir </> "config.toml"
createDirectoryIfMissing True configDir
TIO.writeFile configPath configText
exePath <- findExecutable "tui-launcher"
case exePath of
Nothing -> fail "Could not find tui-launcher executable in PATH"
Just binaryPath -> pure (binaryPath, configPath)
-- | Explicit launcher config used by the TUISpec tests.
launcherConfig :: T.Text
launcherConfig =
T.unlines
[ "[layout]"
, "tile-width = 18"
, "tile-height = 5"
, "tile-spacing = 1"
, ""
, "[[entries]]"
, "name = \"Logs\""
, "command = \"printf 'not-a-shell\\\\n'; exec sh\""
, "color = \"red\""
, ""
, "[[entries]]"
, "name = \"InteractiveShell\""
, "command = \"exec /bin/sh\""
, "color = \"green\""
]