Repository: teampoltergeist/poltergeist

Issue #493: send_keys with arrow keys does not persist navigation
Created: 2014-05-16T21:45:28Z
In the Capybara test below, note how sending :Left does not persist the navigation.
require "spec_helper"

feature "pressing Left on contenteditable", :js do
  specify do
    visit "/"
    element = find("[contenteditable]")
    expect(element).to have_text("")

    element.native.send_keys("H", "elo")
    expect(element).to have_text("Helo") # passes, should

    element.native.send_keys(:Left, "l")
    expect(element).to have_text("Hello") # passes, should

    element.native.send_keys("A")
    expect(element).to have_text("HelloA") # passes, SHOULD NOT, should be "HellAo"

    element.native.send_keys(:Left)
    element.native.send_keys("X")
    expect(element).to have_text("HellXAo") # fails
  end
end
The issue is that send_keys(:Left, "foo") will indeed send :Left and type "foo" as if the user moved left. But subsequent send_keys act as if the caret position is at the far-right of whatever the current text is.
So the final passing test above doesn't remember that we're actually to the left of "o". Similarly, the final test fails because all send_keys forget the real caret position that would exist in a browser.
One work-around in simple cases is to buffer all send_keys until the very end, just before verifying text contents, then combining all arguments into one. But this doesn't apply to more complex testing situations.
Isn't this a phantomjs issue?
I don't think so. As of phantomjs ariya/phantomjs@62fbad4 (master as of this writing) this test passes:
it("should handle arrow keys for contenteditable", function() {
    runs(function() {
        page.content = '<div contenteditable="true"></div>';
        page.evaluate(function() {
            // move selection to the start of content editable
            var range, selection, element;
            element = document.querySelector("div");
            range = document.createRange();
            range.selectNodeContents(element);
            range.setStart(element, 0);
            range.collapse(true);
            selection = document.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
        });
        page.sendEvent("keypress", "abcd");

        var text = page.evaluate(function() {
            return document.querySelector("div").textContent;
        });
        expect(text).toEqual("abcd");

        page.sendEvent("keypress", page.event.key.Left);
        page.sendEvent("keypress", page.event.key.Left);
        page.sendEvent("keypress", "X");

        var text = page.evaluate(function() {
            return document.querySelector("div").textContent;
        });

        expect(text).toEqual("abXcd");
    });
});

Duplicate issue #488: Any way of setting field text without triggering a blur?
Created: 2014-05-06T04:05:08Z
I'm implementing a Trello-style inline edit functionality, where clicking on a piece of text replaces it with an input field. Focusing out of the input field leaves the edits but doesn't save them, pressing enter triggers a save.
This turns out to be essentially impossible to test with Poltergeist: I can't use send_key to fire the enter keypress on the input, as the act of filling it in with set has already blurred it and therefore caused it to disappear and be replaced by static text. The end of the set method always triggers blur on the input:
https://github.com/teampoltergeist/poltergeist/blob/master/lib/capybara/poltergeist/client/agent.coffee#L203
(I also can't add a "\n" to the end of the input, as the keycode and which on the triggered event always come up as 0, which I think is because of https://bugs.webkit.org/show_bug.cgi?id=16735).
Ideally there would be a way to fill out a form field without automatically blurring it in the process.

Closing comment (2014-05-16T22:36:01Z): Seems related to #493