[{"name":"Snapshot","comment":" Snapshot testing framework for Elm.\n\n    module Snapshots exposing (run)\n\n    import Json.Encode\n    import Pages.Script exposing (Script)\n    import Snapshot\n\n    run : Script\n    run =\n        Snapshot.run \"Snapshots\"\n            [ Snapshot.test \"greeting\" <|\n                \\() -> \"Hello, \" ++ \"World\" ++ \"!\"\n            , Snapshot.json \"user\" <|\n                \\() ->\n                    Json.Encode.object\n                        [ ( \"name\", Json.Encode.string \"Alice\" )\n                        , ( \"age\", Json.Encode.int 30 )\n                        ]\n            ]\n\nRun with `elm-pages run src/Snapshots.elm --approve=prompt` and press Enter to approve each snapshot. Commit the `.approved` files to git.\n\n@docs Test, run, test, json, custom, checkedTest, checkedJson, checkedCustom, taskTest, taskJson, taskCustom, withScrubbers, describe, only, skip, todo\n\n","unions":[{"name":"Test","comment":" An opaque type representing a snapshot test or group of tests.\n\nCreate tests using `test`, `json`, `custom`, or their `task*` variants.\nGroup related tests using `describe`.\n\n","args":[],"cases":[]}],"aliases":[],"values":[{"name":"checkedCustom","comment":" Create a snapshot test with a custom printer that validates before snapshotting.\n\n    Snapshot.checkedCustom xmlPrinter \"parsed xml\" <|\n        \\() ->\n            Xml.parse rawXml\n                |> Result.mapError Xml.errorToString\n\n","type":"Snapshot.Printer.Printer a -> String.String -> (() -> Result.Result String.String a) -> Snapshot.Test"},{"name":"checkedJson","comment":" Create a JSON snapshot test that validates before snapshotting.\n\n    Snapshot.checkedJson \"decoded user\" <|\n        \\() ->\n            Json.Decode.decodeString userDecoder jsonString\n                |> Result.mapError Json.Decode.errorToString\n\n","type":"String.String -> (() -> Result.Result String.String Json.Encode.Value) -> Snapshot.Test"},{"name":"checkedTest","comment":" Create a snapshot test that validates before snapshotting.\n\n    Snapshot.checkedTest \"parsed config\" <|\n        \\() ->\n            Config.parse rawInput\n                |> Result.map Config.toString\n\nIf the Result is `Err`, the test fails with that error message and no\nsnapshot is written. If `Ok`, the value is snapshotted normally.\n\nThis is useful when test setup might fail (parsing, validation, etc.)\nand you want to catch those failures before snapshotting.\n\n","type":"String.String -> (() -> Result.Result String.String String.String) -> Snapshot.Test"},{"name":"custom","comment":" Create a snapshot test with a custom printer.\n\n    Snapshot.custom myXmlPrinter \"config file\" <|\n        \\() ->\n            buildConfig options\n\nUse this when you need a custom `a -> String` conversion.\n\n","type":"Snapshot.Printer.Printer a -> String.String -> (() -> a) -> Snapshot.Test"},{"name":"describe","comment":" Group related tests together.\n\n    Snapshot.describe \"Date formatting\"\n        [ Snapshot.test \"ISO format\" <|\n            \\() -> Date.toIsoString date\n        , Snapshot.test \"human readable\" <|\n            \\() -> Date.toHumanString date\n        ]\n\nTest names are prefixed with the group name, separated by \" / \".\nSnapshot files are stored in subdirectories matching the group structure.\n\n","type":"String.String -> List.List Snapshot.Test -> Snapshot.Test"},{"name":"json","comment":" Create a snapshot test for JSON values with pretty printing.\n\n    Snapshot.json \"user data\" <|\n        \\() ->\n            User.encode user\n\nUses 2-space indentation. Keys are sorted alphabetically for deterministic output.\n\n","type":"String.String -> (() -> Json.Encode.Value) -> Snapshot.Test"},{"name":"only","comment":" Run only this test (and any other tests marked with `only`).\n\n    Snapshot.only <|\n        Snapshot.test \"focus on this\" <|\n            \\() -> workInProgress\n\nWhen any test is marked with `only`, all tests without `only` will be skipped.\nUse this during development to focus on specific tests.\n\n**Important:** Using `only` causes the test suite to fail, preventing you from\naccidentally committing focused tests to CI.\n\nNote: `skip` takes precedence over `only` - a skipped test won't run even\nif it's inside an `only` block.\n\n","type":"Snapshot.Test -> Snapshot.Test"},{"name":"run","comment":" Run a list of snapshot tests as an elm-pages Script.\n\n    -- In your Snapshots.elm script:\n    run : Script\n    run =\n        Snapshot.run \"Snapshots\"\n            [ Snapshot.test \"greeting\" <| \\() -> greet \"World\"\n            , Snapshot.json \"config\" <| \\() -> encodeConfig config\n            ]\n\nThe first argument is the script name (typically matching the module name).\nThis organizes snapshots into `snapshots/<ScriptName>/` directories,\nallowing multiple snapshot scripts in the same project.\n\nSupports CLI options:\n\n  - `--approve=all` - Approve all new/changed snapshots\n  - `--approve=prompt` - Interactive per-snapshot approval\n  - `--approve-only \"test name\"` - Approve a specific test\n  - `--ci` - Compact output for CI environments\n  - `--list` - List all test names without running\n  - `--prune` - Remove obsolete snapshot files\n  - `--reporter <tool>` - Open diff tool for failures (code, opendiff, meld, ksdiff, kdiff3, diff, or any command)\n\n","type":"String.String -> List.List Snapshot.Test -> Pages.Script.Script"},{"name":"skip","comment":" Skip this test.\n\n    Snapshot.skip <|\n        Snapshot.test \"broken test\" <|\n            \\() -> brokenCode\n\nThe test will be reported as skipped but won't be executed.\nUse this to temporarily disable tests without deleting them.\n\n**Important:** Using `skip` causes the test suite to fail, preventing you from\naccidentally committing skipped tests to CI.\n\nNote: `skip` takes precedence over `only` - a skipped test won't run even\nif it's inside an `only` block.\n\n","type":"Snapshot.Test -> Snapshot.Test"},{"name":"taskCustom","comment":" Create a BackendTask-powered snapshot test with a custom printer.\n\n    Snapshot.taskCustom myPrinter \"fetched data\" <|\n        fetchData\n            |> BackendTask.allowFatal\n\n","type":"Snapshot.Printer.Printer a -> String.String -> BackendTask.BackendTask FatalError.FatalError a -> Snapshot.Test"},{"name":"taskJson","comment":" Create a BackendTask-powered snapshot test for JSON values.\n\n    Snapshot.taskJson \"api response\" <|\n        Http.get url decoder\n            |> BackendTask.allowFatal\n\nUses 2-space indentation. Keys are sorted alphabetically for deterministic output.\n\n","type":"String.String -> BackendTask.BackendTask FatalError.FatalError Json.Encode.Value -> Snapshot.Test"},{"name":"taskTest","comment":" Create a BackendTask-powered snapshot test for string output.\n\n    Snapshot.taskTest \"elm.json deps\" <|\n        File.rawFile \"elm.json\"\n            |> BackendTask.allowFatal\n\nUse this for tests that need IO (file reading, HTTP, etc).\n\n","type":"String.String -> BackendTask.BackendTask FatalError.FatalError String.String -> Snapshot.Test"},{"name":"test","comment":" Create a snapshot test that compares string output.\n\n    Snapshot.test \"greeting\" <|\n        \\() ->\n            greet \"World\"\n\nThis is the most common form - use when your function already returns a String.\n\n","type":"String.String -> (() -> String.String) -> Snapshot.Test"},{"name":"todo","comment":" A placeholder for a test you intend to write later.\n\n    Snapshot.todo \"handle edge case where input is empty\"\n\nThe test will be reported as a todo item. This is useful for jotting down\ntest ideas without implementing them immediately.\n\n**Important:** Using `todo` causes the test suite to fail, preventing you from\naccidentally committing incomplete tests to CI.\n\n","type":"String.String -> Snapshot.Test"},{"name":"withScrubbers","comment":" Add scrubbers to a test with non-deterministic output.\n\n    Snapshot.test \"log entry\" (\\() -> formatLog entry)\n        |> Snapshot.withScrubbers [ Scrubber.timestamp ]\n\n    Snapshot.json \"api response\" (\\() -> encodeResponse resp)\n        |> Snapshot.withScrubbers [ Scrubber.guid, Scrubber.timestamp ]\n\nScrubbers run after printing, replacing patterns like timestamps\nand GUIDs with stable placeholders.\n\n","type":"List.List Snapshot.Scrubber.Scrubber -> Snapshot.Test -> Snapshot.Test"}],"binops":[]},{"name":"Snapshot.Printer","comment":" Printers convert domain objects to strings for snapshot comparison.\n\nEvery snapshot test has a printer (even if it's just identity).\nThe printer's job is to create a human-readable, diffable representation.\n\n**Best practices (Emily Bache):**\n\n  - Keep lines short for easy diff viewing\n  - JSON can be tricky - prefer pretty-printing\n  - Include inputs in output for context\n  - Change printers in separate commits from logic changes\n\n\n# Definition\n\n@docs Printer\n\n\n# Common Printers\n\n@docs string, json, elm\n\n\n# Customization\n\n@docs withExtension\n\n","unions":[],"aliases":[{"name":"Printer","comment":" A printer converts a value of type `a` to a String and specifies\nthe file extension for syntax highlighting in diff tools.\n\nThe extension is used to generate snapshot filenames like:\n\n    test_name.approved.json\n\n    test_name.received.txt\n\n","args":["a"],"type":"{ extension : String.String, print : a -> String.String }"}],"values":[{"name":"elm","comment":" Pretty-prints any Elm value using elm-format style. This requires\n`Debug.toString` to be passed as the first argument.\n\nSince published packages cannot use `Debug.toString` directly, you must pass\nit in as the first argument:\n\n    Snapshot.custom (Printer.elm Debug.toString) \"user model\" <|\n        \\() -> model.user\n\nA common pattern is to create a helper in your test file:\n\n    elmPrinter : Printer a\n    elmPrinter =\n        Printer.elm Debug.toString\n\n    -- Then use it in your tests:\n    Snapshot.custom elmPrinter \"user model\" <|\n        \\() -> model.user\n\nThe output is formatted as valid Elm syntax, making diffs easy to read.\n\nProduces `.elm` files for syntax highlighting in diff tools.\n\n**Dependencies:** This printer relies on `kraklin/elm-debug-parser` and\n`lue-bird/elm-syntax-format` to parse and format the debug output.\n\n","type":"(a -> String.String) -> Snapshot.Printer.Printer a"},{"name":"json","comment":" JSON pretty-printer with sorted keys and 2-space indentation.\n\n    Snapshot.json \"user data\" <|\n        \\() -> User.encode user\n\n**Keys are sorted alphabetically** at all nesting levels for deterministic\noutput. This matches the behavior of Go's `json.Marshal` and Jest's\n`pretty-format` - the modern consensus for testing tools.\n\nUses 2-space indentation, which is the most common convention for JSON\nand produces readable diffs with reasonable line lengths.\n\nProduces `.json` files for syntax highlighting in diff tools.\n\n","type":"Snapshot.Printer.Printer Json.Encode.Value"},{"name":"string","comment":" Identity printer for string output.\n\n    Snapshot.custom Printer.string \"log output\" <|\n        \\() -> formatLog entry\n\nProduces `.txt` files by default.\n\n","type":"Snapshot.Printer.Printer String.String"},{"name":"withExtension","comment":" Change the file extension of a printer.\n\n    xmlPrinter : Printer String\n    xmlPrinter =\n        Printer.string\n            |> Printer.withExtension \"xml\"\n\nUseful when the content type doesn't match the default extension.\n\n","type":"String.String -> Snapshot.Printer.Printer a -> Snapshot.Printer.Printer a"}],"binops":[]},{"name":"Snapshot.ProgramTest","comment":" High-level snapshot testing for `ProgramTest` programs.\n\n    module Snapshots exposing (run)\n\n    import Html exposing (Html, button, div, span, text)\n    import Html.Events exposing (onClick)\n    import Pages.Script exposing (Script)\n    import ProgramTest exposing (ProgramTest)\n    import Snapshot\n    import Snapshot.ProgramTest\n    import Test.Html.Selector as Selector\n\n    startCounterApp : ProgramTest { count : Int } () ()\n    startCounterApp =\n        ProgramTest.createSandbox\n            { init = { count = 0 }\n            , update = \\() model -> { model | count = model.count + 1 }\n            , view =\n                \\model ->\n                    div []\n                        [ button [ onClick () ] [ text \"++\" ]\n                        , span [] [ text (String.fromInt model.count) ]\n                        ]\n            }\n            |> ProgramTest.start ()\n\n    run : Script\n    run =\n        Snapshot.run \"Snapshots\"\n            [ Snapshot.ProgramTest.view [] \"initial view\" <|\n                \\() -> startCounterApp\n            , Snapshot.ProgramTest.view [ Selector.tag \"span\" ] \"counter display\" <|\n                \\() ->\n                    startCounterApp\n                        |> ProgramTest.clickButton \"++\"\n            , Snapshot.ProgramTest.model Debug.toString \"model after click\" <|\n                \\() ->\n                    startCounterApp\n                        |> ProgramTest.clickButton \"++\"\n            ]\n\nAfter running `elm-pages run src/Snapshots.elm --approve=all`, you will have these files on disk:\n\n`initial_view.approved.html`:\n\n    <div>\n        <button>++</button>\n        <span>0</span>\n    </div>\n\n`counter_display.approved.html`:\n\n    <span>1</span>\n\n`model_after_click.approved.elm`:\n\n    { count = 1 }\n\n@docs view, model\n\n","unions":[],"aliases":[],"values":[{"name":"model","comment":" Create a snapshot test of the model from a `ProgramTest`.\n\nThe model is pretty-printed as formatted Elm syntax using `Printer.elm`,\nproducing `.elm` snapshot files with proper syntax highlighting.\n\nThe first argument must be `Debug.toString` (published packages cannot\ncall it directly, so you must pass it in).\n\n    Snapshot.ProgramTest.model Debug.toString \"model state\" <|\n        \\() ->\n            myProgram\n                |> ProgramTest.clickButton \"++\"\n\n","type":"(a -> String.String) -> String.String -> (() -> ProgramTest.ProgramTest a msg effect) -> Snapshot.Test"},{"name":"view","comment":" Create a snapshot test of the rendered view HTML from a `ProgramTest`.\n\nThe first argument is a list of selectors to scope the snapshot to a\nsubtree of the view. Pass an empty list to snapshot the entire view.\n\n    Snapshot.ProgramTest.view [] \"full view\" <|\n        \\() -> myProgram\n\n    Snapshot.ProgramTest.view [ Selector.tag \"span\" ] \"counter display\" <|\n        \\() ->\n            myProgram\n                |> ProgramTest.clickButton \"++\"\n\n","type":"List.List Test.Html.Selector.Selector -> String.String -> (() -> ProgramTest.ProgramTest model msg effect) -> Snapshot.Test"}],"binops":[]},{"name":"Snapshot.Scrubber","comment":" Scrubbers clean non-deterministic content from snapshot output.\n\n\"Fundamentally, a scrubber is a function that takes a string and returns a string.\"\n— [ApprovalTests documentation](https://approvaltests.com/docs/reference/Scrubbers/)\n\nScrubbers are applied AFTER the printer converts your value to a string.\nThey replace variable content (timestamps, GUIDs, etc.) with stable placeholders.\n\nSince `Scrubber` is just a type alias for `String -> String`, any function\nwith that signature works as a scrubber:\n\n    myScrubber : Scrubber\n    myScrubber =\n        String.replace \"secret\" \"[REDACTED]\"\n\n\n# Definition\n\n@docs Scrubber\n\n\n# Built-in Scrubbers\n\n@docs timestamp, guid, date\n\n\n# Custom Scrubbers\n\n@docs regex, numbered, lines\n\n\n# Composition\n\n@docs all\n\n","unions":[],"aliases":[{"name":"Scrubber","comment":" A scrubber transforms a string, typically replacing non-deterministic\ncontent with stable placeholders.\n","args":[],"type":"String.String -> String.String"}],"values":[{"name":"all","comment":" Compose multiple scrubbers into one. Applied first to last.\n\n    Scrubber.all\n        [ Scrubber.timestamp\n        , Scrubber.guid\n        , Scrubber.regex \"v\\\\d+\\\\.\\\\d+\\\\.\\\\d+\" \"[VERSION]\"\n        ]\n\n","type":"List.List Snapshot.Scrubber.Scrubber -> String.String -> String.String"},{"name":"date","comment":" Replace dates matching a format pattern with `[DATE-1]`, `[DATE-2]`, etc.\n\nProvide a format string using these tokens:\n\n  - `YYYY` - 4-digit year\n  - `MM` - 2-digit month (01-12)\n  - `DD` - 2-digit day (01-31)\n  - `hh` - 2-digit hour (00-23)\n  - `mm` - 2-digit minute (00-59)\n  - `ss` - 2-digit second (00-59)\n\nExamples:\n\n    -- Match \"2024-01-15\"\n    Scrubber.date \"YYYY-MM-DD\"\n\n    -- Match \"01/15/2024\"\n    Scrubber.date \"MM/DD/YYYY\"\n\n    -- Match \"15-Jan-2024\"\n    Scrubber.date \"DD-Mon-YYYY\"\n\n    -- Match \"2024-01-15 10:30:00\"\n    Scrubber.date \"YYYY-MM-DD hh:mm:ss\"\n\nLike `guid`, the same date appearing multiple times gets the same number.\n\n","type":"String.String -> Snapshot.Scrubber.Scrubber"},{"name":"guid","comment":" Replace GUIDs/UUIDs with stable placeholders like `[GUID-1]`, `[GUID-2]`.\n\nPreserves referential equality: the same GUID appearing multiple times\nin the output will get the same placeholder number.\n\nMatches standard UUID format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`\n\n","type":"Snapshot.Scrubber.Scrubber"},{"name":"lines","comment":" Remove or keep lines based on a predicate.\n\n    -- Remove all lines containing \"DEBUG\"\n    Scrubber.lines (not << String.contains \"DEBUG:\")\n\n    -- Keep only lines starting with \"ERROR\"\n    Scrubber.lines (String.startsWith \"ERROR\")\n\nThe predicate returns `True` for lines to keep, `False` for lines to remove.\n\n","type":"(String.String -> Basics.Bool) -> String.String -> String.String"},{"name":"numbered","comment":" Replace regex matches with numbered placeholders like `[LABEL-1]`, `[LABEL-2]`.\n\nPreserves referential equality: the same value appearing multiple times\ngets the same placeholder number.\n\n    -- User IDs: \"user-123\" and \"user-456\" → \"[USER-1]\" and \"[USER-2]\"\n    Scrubber.numbered \"user-\\\\d+\" \"USER\"\n\n    -- Request IDs that appear multiple times get consistent numbers\n    Scrubber.numbered \"req-[a-z0-9]+\" \"REQUEST\"\n\nThe label is wrapped in brackets with a number: `[LABEL-1]`, `[LABEL-2]`, etc.\n\n","type":"String.String -> String.String -> String.String -> String.String"},{"name":"regex","comment":" Replace all matches of a regex pattern with a fixed string.\n\n    -- Replace version numbers\n    Scrubber.regex \"v\\\\d+\\\\.\\\\d+\\\\.\\\\d+\" \"[VERSION]\"\n\n    -- Replace port numbers\n    Scrubber.regex \":\\\\d{4,5}\" \":[PORT]\"\n\nNote: Uses Elm's Regex module. Invalid patterns are silently ignored.\n\n","type":"String.String -> String.String -> String.String -> String.String"},{"name":"timestamp","comment":" Replace ISO 8601 timestamps with `[TIMESTAMP]`.\n\nMatches patterns like:\n\n  - `2024-01-15T10:30:00Z`\n  - `2024-01-15T10:30:00.123Z`\n  - `2024-01-15T10:30:00+05:00`\n  - `2024-01-15 10:30:00`\n\n","type":"Snapshot.Scrubber.Scrubber"}],"binops":[]}]