Skip to content
This repository has been archived by the owner on Jun 28, 2023. It is now read-only.

The ability to send keystrokes to the browser. #61

Open
rburton opened this issue Nov 12, 2015 · 6 comments
Open

The ability to send keystrokes to the browser. #61

rburton opened this issue Nov 12, 2015 · 6 comments

Comments

@rburton
Copy link

rburton commented Nov 12, 2015

I was looking to see if the API has the ability to send keystrokes, but I was unable to locate it. Is this possible?

Sorry, I couldn't find any documentation and I've been reading through the code and API trying to locate this. It seems like I would have to implement this via the agouti.Session and the JSON protocol.

@sclevine
Copy link
Owner

Hi @rburton,

There are a few ways to do this:

  • If you're looking to clear an element and enter text into it, see Selection.Fill().
  • If you're looking to send keystrokes directly to an element, Selection.Elements() will return api.Elements that have a Value() method. (This is the standard Selenium sendKeys functionality.)
  • If you're looking to send keystrokes to the current active element, you could do this:
keystrokes := map[string][]string{"value": {"some keystrokes"}}
page.Session().Send("POST", "keys", keystrokes, nil)

Let me know if the third case is what you're looking for. It should eventually be exposed with page.Session().Keys(values string), and adding that method is trivial.

Hope this helps!
Stephen

@rburton
Copy link
Author

rburton commented Nov 12, 2015

The latter is exactly what I was looking to do. In fact, I created a function called SendKeys that does exactly what you just provided.

One other request is around the ability to wait for elements to be visible. I noticed there's a recommendation in using http://onsi.github.io/gomega/#making-asynchronous-assertions but what I'm actually looking for is more on the lines to pause the execution until either a timeout period is reached or the element is displayed.

In Java using RemoteWebDriver they have WebDriverWait and you would do something like

wait.until(presenceOfAllElementsLocatedBy(cssSelector("#name")));

One more last question :) It would be very powerful to obtain the PID of the PhantomJS process that's running so users could check to see how much memory the process is using. Overtime, Phantom.js tends to grow in memory usage, so it would be awesome to check the memory size and restart the process if it starts to exceed a certain amount of memory.

Keep up the great work.

@sclevine
Copy link
Owner

Done (6bebd20). I've seen most people use the Value() method for this, but I'm happy to make the API more complete.

If you want to wait for an element to become visible on the page with a provided timeout, use the Agouti BeVisible matcher with Gomega's Eventually like this:

import (
    ...
    . "github.com/sclevine/agouti/matchers"
    . "github.com/onsi/gomega"
    ...
)
...
Eventually(page.Find("#my_element"), "100s").Should(BeVisible()) 

If you only care about DOM presence:

Eventually(page.Find("#my_element"), "100s").Should(BeFound()) 

Exposing the PID of the api.WebDriver process should be relatively straightforward. The agouti/api/internal/service.Service.Start() method could return the PID from the *exec.Cmd, and we could store it on the api.WebDriver. I can do this when I have more time, but feel free to open a PR :).

Thanks!
Stephen

@rburton
Copy link
Author

rburton commented Nov 12, 2015

I'll take the information you provided and work on a push request.

In addition, I'm going to work on a way to pass cli options to Phantom.js so a user can avoid loading imagines for instance.

@mattetti
Copy link

Just a quick note that we also use the Keys function, note that you might want to make the special key codes available directly in Agouti:

const (
    NULL            = "\uE000"
    CANCEL          = "\uE001"
    HELP            = "\uE002"
    BACK_SPACE      = "\uE003"
    TAB             = "\uE004"
    CLEAR           = "\uE005"
    RETURN          = "\uE006"
    ENTER           = "\uE007"
    SHIFT           = "\uE008"
    LEFT_SHIFT      = "\uE008"
    CONTROL         = "\uE009"
    LEFT_CONTROL    = "\uE009"
    ALT             = "\uE00A"
    LEFT_ALT        = "\uE00A"
    PAUSE           = "\uE00B"
    ESCAPE          = "\uE00C"
    SPACE           = "\uE00D"
    PAGE_UP         = "\uE00E"
    PAGE_DOWN       = "\uE00F"
    END             = "\uE010"
    HOME            = "\uE011"
    LEFT            = "\uE012"
    ARROW_LEFT      = "\uE012"
    UP              = "\uE013"
    ARROW_UP        = "\uE013"
    RIGHT           = "\uE014"
    ARROW_RIGHT     = "\uE014"
    DOWN            = "\uE015"
    ARROW_DOWN      = "\uE015"
    INSERT          = "\uE016"
    DELETE          = "\uE017"
    SEMICOLON       = "\uE018"
    EQUALS          = "\uE019"
    NUMPAD0         = "\uE01A"
    NUMPAD1         = "\uE01B"
    NUMPAD2         = "\uE01C"
    NUMPAD3         = "\uE01D"
    NUMPAD4         = "\uE01E"
    NUMPAD5         = "\uE01F"
    NUMPAD6         = "\uE020"
    NUMPAD7         = "\uE021"
    NUMPAD8         = "\uE022"
    NUMPAD9         = "\uE023"
    MULTIPLY        = "\uE024"
    ADD             = "\uE025"
    SEPARATOR       = "\uE026"
    SUBTRACT        = "\uE027"
    DECIMAL         = "\uE028"
    DIVIDE          = "\uE029"
    F1              = "\uE031"
    F2              = "\uE032"
    F3              = "\uE033"
    F4              = "\uE034"
    F5              = "\uE035"
    F6              = "\uE036"
    F7              = "\uE037"
    F8              = "\uE038"
    F9              = "\uE039"
    F10             = "\uE03A"
    F11             = "\uE03B"
    F12             = "\uE03C"
    META            = "\uE03D"
    COMMAND         = "\uE03D"
    ZENKAKU_HANKAKU = "\uE040"
)

@cakesmith
Copy link

Is there a way to send chords, or a keydown/keyup? For example I want to send Ctrl + t to open a new tab, but it seems that this isn't quite working

ctrl := "\uE009"
err = page.Find("body").SendKeys(ctrl + "t")

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants