API

Note

We try to document the basics here, but it is not meant as a replacement for the upstream documentation. If you need general help we recommend looking at the test engine wiki, and possibly at the documentation comments in these header files:

There are two major parts of the test engine:

  • The Engine itself. This is the class that executes the tests and handles things like interacting with the GUI.
  • The Test context API, which is what you'll use to control the GUI and write the tests.
Danger

For the sake of simplicitly certain parts of the API are not memory-safe. This means that some test engine types are wrapped as raw pointers that are owned by C++ rather than Julia, which means that using them after they have been free'd will cause segfaults. All memory-unsafe types are marked as such in their docstrings.

Because of all that, we recommend using such types only temporarily in the style recommended by the upstream examples. This style is good:

# The test object is never even assigned to a variable
@register_test(engine, "foo", "bar") do ctx
    ...
end

This style is less good:

all_tests = []
t = @register_test(engine, "foo", "bar")
t.TestFunc = ...

# Dangerous because it allows `t` to potentially be accessed after the
# engine has been destroyed.
push!(all_tests, t)

Note that in all the examples in the docstrings below we assume that we have already evaluated:

import CImGui as ig
using ImGuiTestEngine
import ImGuiTestEngine as te

Engine

ImGuiTestEngine.CreateContextFunction
CreateContext(
;
    exit_on_completion,
    show_test_window
) -> ImGuiTestEngine.Engine

Create a test engine context. The keyword arguments don't do anything in this library, they're used to support the test engine in CImGui.jl's renderloop.

Arguments

  • exit_on_completion=true: Exit the program after the tests have completed.
  • show_test_window=true: Call ShowTestEngineWindows() while running the tests.

Examples

engine = te.CreateContext()
source
ImGuiTestEngine.DestroyContextFunction
DestroyContext(engine::ImGuiTestEngine.Engine; throw)

Destroy a test engine context.

Arguments

  • throw=true: Whether to throw an exception if the engine has already been destroyed.

Examples

engine = te.CreateContext()
te.DestroyContext(engine)
source
ImGuiTestEngine.RegisterTestFunction
RegisterTest(
    engine::ImGuiTestEngine.Engine,
    category,
    name
) -> Ptr{ImGuiTestEngine.lib.ImGuiTest}
RegisterTest(
    engine::ImGuiTestEngine.Engine,
    category,
    name,
    src_file
) -> Ptr{ImGuiTestEngine.lib.ImGuiTest}
RegisterTest(
    engine::ImGuiTestEngine.Engine,
    category,
    name,
    src_file,
    src_line
) -> Ptr{ImGuiTestEngine.lib.ImGuiTest}

Prefer calling IMREGISTERTEST().

Upstream link.

source
ImGuiTestEngine.QueueTestFunction
QueueTest(
    engine::ImGuiTestEngine.Engine,
    test::ImGuiTestEngine.ImGuiTest
)
QueueTest(
    engine::ImGuiTestEngine.Engine,
    test::ImGuiTestEngine.ImGuiTest,
    run_flags
)

Upstream link.

source
ImGuiTestEngine.QueueTestsFunction
QueueTests(
    engine::ImGuiTestEngine.Engine,
    group::ImGuiTestEngine.lib.ImGuiTestGroup
)
QueueTests(
    engine::ImGuiTestEngine.Engine,
    group::ImGuiTestEngine.lib.ImGuiTestGroup,
    filter
)
QueueTests(
    engine::ImGuiTestEngine.Engine,
    group::ImGuiTestEngine.lib.ImGuiTestGroup,
    filter,
    run_flags
)

Upstream link.

source

Registering tests

Once the engine is set up you can register some tests for it to run:

ImGuiTestEngine.@register_testMacro
@register_test(engine, category::AbstractString, name::AbstractString)::ImGuiTest
@register_test(f::Function, engine,
               category::AbstractString, name::AbstractString)::ImGuiTest

Register a ImGuiTest. Note that it will not be executed until the test is queued, either programmatically with QueueTests() or by the user running it manually through ShowTestEngineWindows().

Examples

If you only need to set TestFunc you can use do-syntax:

engine = te.CreateContext()
@register_test(engine, "foo", "bar") do
    @imtest ctx isa te.TestContext
end

To set GuiFunc as well you'll need to set the GuiFunc property:

engine = te.CreateContext()
t = @register_test(engine, "foo", "bar")
t.GuiFunc = () -> begin
    ig.Begin("Foo")
    ig.End()
end
t.TestFunc = () -> @info "Hello world!"
source
ImGuiTestEngine.ImGuiTestType
mutable struct ImGuiTest

Wrapper around the upstream ImGuiTest. Don't create this yourself, use @register_test(). Once it's created you can assign functions to these properties:

  • GuiFunc::Function, for standalone GUI code that you want to run/test. This shouldn't be necessary if you're testing your own GUI.
  • TestFunc::Function, for tests that you want to execute.

The functions you assign should not take any arguments, and any return value will be discarded.

Danger

This a memory-unsafe type, only use it while the engine is alive.

source

Within the tests you will often want to refer to parts of your interface by named reference. In the C++ API this is done with the ImGuiTestRef type but with ImGuiTestEngine.jl you should use either strings or integers and they will automatically be converted.

Test context

Inside GuiFunc and TestFunc you can use any methods of the test context API to control and test the GUI. It's not safe to use them outside of a GuiFunc/TestFunc.

ImGuiTestEngine.@imcheckMacro
@imcheck expr

A port of the upstream IM_CHECK() macro. Like the upstream macro, this will return early from the calling function if expr evaluates to false. Prefer using it over @test because it will register test results with the test engine, which can be convenient if you're using the built-in test engine window (see ShowTestEngineWindows()).

@imcheck hooks into @testset's by default, so a failure will be recorded with your Julia Test tests as well as with the test engine. If this is not wanted it can be disabled by passing jltest=false.

Note

A limitation of the current implementation is that nicely parsing the expression, e.g. to display both arguments of an equality, is not supported.

Examples

engine = te.CreateContext()
@register_test(engine, "foo", "bar") do
    # This record the result with `Test` as well as the test engine
    @imcheck false

    # This will only record the result with the test engine
    @imcheck false jltest=false
end
source
ImGuiTestEngine.OpenAndCloseFunction
OpenAndClose(
    f,
    test_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)

A helper function that will ensure test_ref is open, execute f(), and close test_ref again. A typical use would be to open a section, run some tests, and then close the section again (handy for re-runnable tests).

Examples

@register_test(engine, "foo", "bar") do
    OpenAndClose("My section") do
        # ...
    end
end
source
OpenAndClose(
    test_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)

Open and then close test_ref.

Examples

@register_test(engine, "foo", "bar") do
    OpenAndClose("My section")
end
source
ImGuiTestEngine.FinishFunction
Finish()
Finish(status::ImGuiTestEngine.lib.ImGuiTestStatus)

Set test status and stop running. Usually called when running test logic from GuiFunc() only.

Upstream link.

source
ImGuiTestEngine.RunChildTestFunction
RunChildTest(
    test_name
) -> ImGuiTestEngine.lib.ImGuiTestStatus
RunChildTest(
    test_name,
    flags
) -> ImGuiTestEngine.lib.ImGuiTestStatus

[Experimental] Run another test from the current test.

Upstream link.

source
ImGuiTestEngine.WindowInfoFunction
WindowInfo(
    window_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
) -> ImGuiTestEngine.lib.ImGuiTestItemInfo
WindowInfo(
    window_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    flags
) -> ImGuiTestEngine.lib.ImGuiTestItemInfo

Upstream link.

source
ImGuiTestEngine.WindowFocusFunction
WindowFocus(
    window_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
WindowFocus(
    window_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    flags
)

Upstream link.

source
ImGuiTestEngine.WindowMoveFunction
WindowMove(
    window_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    pos::Union{CImGui.lib.ImVec2, Tuple{T, T} where T}
)
WindowMove(
    window_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    pos::Union{CImGui.lib.ImVec2, Tuple{T, T} where T},
    pivot::Union{CImGui.lib.ImVec2, Tuple{T, T} where T}
)
WindowMove(
    window_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    pos::Union{CImGui.lib.ImVec2, Tuple{T, T} where T},
    pivot::Union{CImGui.lib.ImVec2, Tuple{T, T} where T},
    flags
)

Upstream link.

source
ImGuiTestEngine.GetIDFunction
GetID(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
) -> UInt32

Upstream link.

source
GetID(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    seed_ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
) -> UInt32

Upstream link.

source
ImGuiTestEngine.GetPosOnVoidFunction
GetPosOnVoid(
    viewport::Union{Ptr{Nothing}, Ref{CImGui.lib.ImGuiViewport}}
) -> Any

Find a point that has no windows // FIXME: This needs error return and flag to enable/disable forcefully finding void.

Upstream link.

source
ImGuiTestEngine.CaptureScreenshotWindowFunction
CaptureScreenshotWindow(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
CaptureScreenshotWindow(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    capture_flags
)

Trigger a screen capture of a single window (== CaptureAddWindow() + CaptureScreenshot()).

Upstream link.

source
ImGuiTestEngine.CaptureScreenshotFunction
CaptureScreenshot(
    engine::ImGuiTestEngine.Engine,
    args::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiCaptureArgs}}
) -> Bool
Warning

This function is internal, it may change in the future.

Upstream link.

source
CaptureScreenshot() -> Bool
CaptureScreenshot(capture_flags) -> Bool

Trigger a screen capture.

Upstream link.

source
ImGuiTestEngine.SetInputModeFunction
SetInputMode(input_mode::CImGui.lib.ImGuiInputSource)

Mouse or Keyboard or Gamepad. In Keyboard or Gamepad mode, actions such as ItemClick or ItemInput are using nav facilities instead of Mouse.

Upstream link.

source
ImGuiTestEngine.ScrollToFunction
ScrollTo(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    axis::CImGui.lib.ImGuiAxis,
    scroll_v
)
ScrollTo(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    axis::CImGui.lib.ImGuiAxis,
    scroll_v,
    flags
)

Upstream link.

source
ImGuiTestEngine.ScrollToItemFunction
ScrollToItem(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    axis::CImGui.lib.ImGuiAxis
)
ScrollToItem(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    axis::CImGui.lib.ImGuiAxis,
    flags
)

Upstream link.

source
ImGuiTestEngine.ItemInfoFunction
ItemInfo(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
) -> ImGuiTestEngine.lib.ImGuiTestItemInfo
ItemInfo(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    flags
) -> ImGuiTestEngine.lib.ImGuiTestItemInfo

Upstream link.

source
ImGuiTestEngine.ItemInfoOpenFullPathFunction
ItemInfoOpenFullPath(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
) -> ImGuiTestEngine.lib.ImGuiTestItemInfo
ItemInfoOpenFullPath(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    flags
) -> ImGuiTestEngine.lib.ImGuiTestItemInfo

Upstream link.

source
ImGuiTestEngine.GatherItemsFunction
GatherItems(
    out_list::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiTestItemList}},
    parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
GatherItems(
    out_list::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiTestItemList}},
    parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    depth
)

Upstream link.

source
ImGuiTestEngine.ItemActionFunction
ItemAction(
    action::ImGuiTestEngine.lib.ImGuiTestAction,
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
ItemAction(
    action::ImGuiTestEngine.lib.ImGuiTestAction,
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    flags
)
ItemAction(
    action::ImGuiTestEngine.lib.ImGuiTestAction,
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    flags,
    action_arg
)

Upstream link.

source
ImGuiTestEngine.ItemClickFunction
ItemClick(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
ItemClick(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    button
)
ItemClick(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    button,
    flags
)

Upstream link.

source
ImGuiTestEngine.ItemActionAllFunction
ItemActionAll(
    action::ImGuiTestEngine.lib.ImGuiTestAction,
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
ItemActionAll(
    action::ImGuiTestEngine.lib.ImGuiTestAction,
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    filter::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiTestActionFilter}}
)

Upstream link.

source
ImGuiTestEngine.ItemOpenAllFunction
ItemOpenAll(
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
ItemOpenAll(
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    depth
)
ItemOpenAll(
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    depth,
    passes
)

Upstream link.

source
ImGuiTestEngine.ItemCloseAllFunction
ItemCloseAll(
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
ItemCloseAll(
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    depth
)
ItemCloseAll(
    ref_parent::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    depth,
    passes
)

Upstream link.

source
ImGuiTestEngine.ItemReadAsScalarFunction
ItemReadAsScalar(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    data_type,
    out_data
) -> Bool
ItemReadAsScalar(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    data_type,
    out_data,
    flags
) -> Bool

Upstream link.

source
ImGuiTestEngine.ItemDragAndDropFunction
ItemDragAndDrop(
    ref_src::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    ref_dst::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
ItemDragAndDrop(
    ref_src::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    ref_dst::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    button
)

Upstream link.

source
ImGuiTestEngine.TableClickHeaderFunction
TableClickHeader(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    label
) -> CImGui.lib.ImGuiSortDirection
TableClickHeader(
    ref::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    label,
    key_mods
) -> CImGui.lib.ImGuiSortDirection

Upstream link.

source
ImGuiTestEngine.DockIntoFunction
DockInto(
    src_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    dst_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String}
)
DockInto(
    src_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    dst_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    split_dir::CImGui.lib.ImGuiDir
)
DockInto(
    src_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    dst_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    split_dir::CImGui.lib.ImGuiDir,
    is_outer_docking
)
DockInto(
    src_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    dst_id::Union{Int64, ImGuiTestEngine.lib.ImGuiTestRef, String},
    split_dir::CImGui.lib.ImGuiDir,
    is_outer_docking,
    flags
)

Upstream link.

source

Other

These functions/types are less commonly used than the ones documented above.

ImGuiTestRef

ImGuiTestRefDesc

ImGuiTestEngine.ImGuiTestRefDescType
ImGuiTestRefDesc(
    ref::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiTestRef}}
) -> ImGuiTestEngine.lib.ImGuiTestRefDesc

Upstream link.

source
ImGuiTestRefDesc(
    ref::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiTestRef}},
    item::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiTestItemInfo}}
) -> ImGuiTestEngine.lib.ImGuiTestRefDesc

Upstream link.

source

ImGuiTestGenericItemStatus

ImGuiTestItemList

ImGuiPerfTool

ImGuiTestEngine.ClearFunction
Clear(self::Ptr{ImGuiTestEngine.lib.ImGuiCaptureImageBuf})

Free allocated memory buffer if such exists.

Upstream link.

source
Clear(self::Ptr{ImGuiTestEngine.lib.ImGuiTestItemList})

Upstream link.

source
Clear(self::Ptr{ImGuiTestEngine.lib.ImGuiTestLog})

Upstream link.

source
Clear(
    self::Ptr{ImGuiTestEngine.lib.ImGuiTestGenericItemStatus}
)

Upstream link.

source
Clear(self::Ptr{ImGuiTestEngine.lib.ImGuiTestGenericVars})

Upstream link.

source
Clear(self::Ptr{ImGuiTestEngine.lib.ImGuiCsvParser})

Free allocated buffers.

Upstream link.

source
Clear(self::Ptr{ImGuiTestEngine.lib.ImGuiTestGatherTask})
Warning

This function is internal, it may change in the future.

Upstream link.

source
Clear(self::Ptr{ImGuiTestEngine.lib.ImGuiPerfTool})

Upstream link.

source
ImGuiTestEngine.GetEntryByBatchIdxFunction
GetEntryByBatchIdx(
    self::Ptr{ImGuiTestEngine.lib.ImGuiPerfTool},
    idx
) -> Ptr{ImGuiTestEngine.lib.ImGuiPerfToolEntry}
GetEntryByBatchIdx(
    self::Ptr{ImGuiTestEngine.lib.ImGuiPerfTool},
    idx,
    perf_name
) -> Ptr{ImGuiTestEngine.lib.ImGuiPerfToolEntry}

Upstream link.

source

ImGuiPerfToolEntry:

ImGuiCaptureContext

ImGuiTestEngine.CaptureUpdateFunction
CaptureUpdate(
    self::Ptr{ImGuiTestEngine.lib.ImGuiCaptureContext},
    args::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiCaptureArgs}}
) -> ImGuiTestEngine.lib.ImGuiCaptureStatus

Upstream link.

source

ImGuiCaptureToolUI

ImGuiTestEngine.ShowCaptureToolWindowFunction
ShowCaptureToolWindow(
    self::Ptr{ImGuiTestEngine.lib.ImGuiCaptureToolUI},
    context::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiCaptureContext}}
)
ShowCaptureToolWindow(
    self::Ptr{ImGuiTestEngine.lib.ImGuiCaptureToolUI},
    context::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiCaptureContext}},
    p_open
)

Render a capture tool window with various options and utilities.

Upstream link.

source

ImGuiCsvParser

ImGuiTestLog

ImGuiTestEngine.ExtractLinesForVerboseLevelsFunction
ExtractLinesForVerboseLevels(
    self::Ptr{ImGuiTestEngine.lib.ImGuiTestLog},
    level_min::ImGuiTestEngine.lib.ImGuiTestVerboseLevel,
    level_max::ImGuiTestEngine.lib.ImGuiTestVerboseLevel,
    out_buffer::Union{Ptr{Nothing}, Ref{CImGui.lib.ImGuiTextBuffer}}
) -> Int32

Upstream link.

source
ImGuiTestEngine.UpdateLineOffsetsFunction
UpdateLineOffsets(
    self::Ptr{ImGuiTestEngine.lib.ImGuiTestLog},
    engine_io::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiTestEngineIO}},
    level::ImGuiTestEngine.lib.ImGuiTestVerboseLevel,
    start
)

Upstream link.

source

ImGuiTestEngine.DestroyFunction

Destructor for ImGuiCaptureImageBuf

source

Destructor for ImGuiCaptureContext

source

Destructor for ImGuiCaptureToolUI

source

Destructor for ImGuiTestItemInfo

source

Destructor for ImGuiTestLog

source

Destructor for ImGuiTest

source

Destructor for ImGuiTestRef

source

Destructor for ImGuiTestRefDesc

source

Destructor for ImGuiTestActionFilter

source

Destructor for ImGuiTestGenericItemStatus

source

Destructor for ImGuiTestGenericVars

source

Destructor for ImGuiCsvParser

source

Destructor for ImGuiPerfToolEntry

source

Destructor for ImGuiPerfToolBatch

source

Destructor for ImGuiPerfTool

source
ImGuiTestEngine.TableGetHeaderIDFunction
TableGetHeaderID(
    table::Union{Ptr{Nothing}, Ref{CImGui.lib.ImGuiTable}},
    column::Union{Ptr{Int8}, Ptr{Nothing}, String}
) -> UInt32
TableGetHeaderID(
    table::Union{Ptr{Nothing}, Ref{CImGui.lib.ImGuiTable}},
    column::Union{Ptr{Int8}, Ptr{Nothing}, String},
    instance_no::Integer
) -> UInt32

Upstream link.

source
TableGetHeaderID(
    table::Union{Ptr{Nothing}, Ref{CImGui.lib.ImGuiTable}},
    column_n::Integer
) -> UInt32
TableGetHeaderID(
    table::Union{Ptr{Nothing}, Ref{CImGui.lib.ImGuiTable}},
    column_n::Integer,
    instance_no::Integer
) -> UInt32

Upstream link.

source
ImGuiTestEngine.PerfToolAppendToCSVFunction
PerfToolAppendToCSV(
    perf_log::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiPerfTool}},
    entry::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiPerfToolEntry}}
)
PerfToolAppendToCSV(
    perf_log::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiPerfTool}},
    entry::Union{Ptr{Nothing}, Ref{ImGuiTestEngine.lib.ImGuiPerfToolEntry}},
    filename
)

Upstream link.

source