:startinsert does not seem to work in tests

I’m writing some tests for a plugin using the busted framework packaged with plenary.nvim. I’m attempting to open a buffer, insert text, do some other things, verify outputs, etc. I’m encountering some weird behavior with :startinsert that I can’t seem to figure out or work around. A minimal repro test:

describe("insert", function()
  it("inserts", function()
    vim.cmd("startinsert!")
    assert(vim.api.nvim_get_mode().mode == "i", "We should be in insert mode by now...")
  end)
end)

The mode is still ‘n’. I thought that maybe the mode doesn’t change immediately and I have to wait, so I tried an async test:

require("plenary.async").tests.add_to_env()
a.describe("insert", function()
  a.it("inserts", function()
    vim.cmd("startinsert!")
    a.util.sleep(1000)
    assert(vim.api.nvim_get_mode().mode == "i", "We should be in insert mode by now...")
  end)
end)

Still no dice (though I’m not 100% certain I’m doing the async properly). Does anyone have any ideas where I’m going wrong here?

Do you specifically need to assert against the current mode? If you want to assert against what happens to the buffer’s content when you insert text / send a specific sequence of keys, you can use vim.api.nvim_feedkeys:

describe("insert", function()
    it("inserts text", function()
        vim.api.nvim_feedkeys("ihello", "x", true)

        assert.equals(vim.api.nvim_buf_get_lines(0, 0, -1, false)[1], "hello")
    end)
end)

The assert is just to show that the mode is incorrect. The full context of this is that I’m trying to get tests for an input modal, and the implementation of that has the call to startinsert. I don’t want to replace that with a feedkeys() because that seems like a hack (in fact, the feedkeys() below it is only there because of bugs with the prompt buffer and will hopefully be removed in a later version).

I could feed in an “i” in the test to force insert mode, but I dislike it because now we’re explicitly asserting that the state is not what it is when used by a person and it makes me lose confidence in the validity of the test. I can resort to that if I can’t find a better solution; I was just hoping that someone would be able to point to something I was doing wrong or a bad assumption I’m making.

:frowning: I just ran into this same issue here: feat(input): support nui.text for options.prompt by MunifTanjim · Pull Request #66 · MunifTanjim/nui.nvim · GitHub