Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

sendKeys() doesn't insert text because focus is on the address bar (firefox only) #1511

Closed
enricorotundo opened this issue Nov 7, 2014 · 20 comments

Comments

@enricorotundo
Copy link

Hi there,
i'm testing a form login contained in a modal.

I'm using the Page Object so i get the element by this:

    this.getRegistrationUserName = function () {
      return element(by.css('#registrationModalView.modal form[name="regForm"] #input_last_name'));
    };

Sometimes sendKeys(string) function execute but the input text-box isn't filled up by the string!
I can say that execute since this.getRegistrationUserName().sendKeys(name).then(function() {console.log("done!");} ) actually prints done!)
The weird is that i notice this issue just for the first input text-box of the form.

After looking #562 seems that executing .clear() on the text-box make sendKeys() working well.

Configuration:

  • protractor 1.4.x
  • chromedriver: 2.9
@enricorotundo
Copy link
Author

Right now i fixed by:

    this.fillLoginForm = function (email, pwd) {
      var self = this;
      this.getLoginModalUserEmail().clear().then(function() {
        self.getLoginModalUserEmail().sendKeys(email);
      });
      this.getLoginModalUserPwd().clear().then(function() {
        self.getLoginModalUserPwd().sendKeys(pwd);
      });
      // when the login button is enablead means that form is fulfilled
      return expect(this.getLoginButton().isEnabled()).toBeTruthy();
    };

Stil testing but seems working pretty well in Chrome and Firefox.
I don't get why i'm supposed to clear first the text-box, @juliemr how could i inspect better this issue?

@juliemr
Copy link
Member

juliemr commented Nov 8, 2014

How do you know that the input text-box isn't being set correctly? Though screenshots or some sort of assertion later?

A couple other noes:

You should be able to just do this like:

this.getLoginModalUserEmail().clear().sendKeys(email);
Does that work for you?

Also, unrelated but your selector raises some red flags. IDs in HTML should be unique, so you should never need to scope them. If you have multiple elements with id input_last_name consider refactoring your templates.

@enricorotundo
Copy link
Author

  1. Basically i see the text input empty in the browser! So my test is stuck since waits for the login button being enabled.
    UPDATE:
    Right now thats my test with the page object:
  it('correct login', function() {
    page.open();
    page.openLoginModal();
    page.fillLoginForm('a@a.aa', 'a');
    page.confirmLogin();
    page.checkRedirection(/profile/, 7000, 'redirection after login not performed');
    page.logout();
  });

page object:

(function () {

  var IndexPage = function () {

    // GETTER elements: navbar
    this.getNavBarRegistrationButton = function () {
      return element(by.css('.navbar #sign-up-navbar > #navbar-registration-button'));
    };

    this.getNavBarLoginButton = function () {
      return element(by.css('.navbar  #navbar-login-button'));
    };

    // GETTER elements: navbar:dropdown

    this.getNavBarDropDownMenu = function () {
      return element(by.css('.user-menu .dropdown-toggle'));
    };

    this.getNavBarDropDownLogoutButton = function () {
      return element(by.css('.user-menu .dropdown-menu #logout-link'));
    };

    // GETTER elements: modal:login

    this.getLoginModal = function () {
      return element(by.css('#loginModalView.modal'));
    };

    this.getLoginModalUserEmail = function () {
      return element(by.css('#loginModalView.modal form[name="loginForm"] #input_email'));
    };

    this.getLoginModalUserPwd = function () {
      return element(by.css('#loginModalView.modal form[name="loginForm"] #input_password'));
    };

    this.getLoginButton = function () {
      return element(by.css('#loginModalView.modal .modal-footer > #modal-login-button'));
    };

    this.getLoginCloseButton = function () {
      return element(by.css('#loginModalView.modal .modal-footer > #modal-close-button'));
    };

    // ACTIONS: global

    this.open = function () {
      browser.get('/view');
      return browser.waitForAngular();
    };

    this.logout = function () {
      this.getNavBarDropDownMenu().click();
      browser.waitForAngular();
      this.getNavBarDropDownLogoutButton().isDisplayed();
      return this.getNavBarDropDownLogoutButton().click();
    };

    this.checkRedirection = function (targetRegex, timeout, message) {
      // explicit wait
      return browser.wait(function() {
        return browser.driver.getCurrentUrl().then(function(url) {
          return targetRegex.test(url); // look for a match of the regex /profile/ in the 'url'
        });
      }, timeout, message);
    };

    // ACTIONS: login

    this.openLoginModal = function () {
      this.getNavBarLoginButton().click();
      browser.waitForAngular();
      return this.getLoginModal().isDisplayed();
    };

    this.fillLoginForm = function (email, pwd) {
      this.getLoginModalUserEmail().clear().sendKeys(email);
      this.getLoginModalUserPwd().clear().sendKeys(pwd);
      // when the login button is enablead means that form is fulfilled
      return expect(this.getLoginButton().isEnabled()).toBeTruthy();
    };

    this.confirmLogin = function () {
      return this.getLoginButton().click();
    };

  };

  module.exports = function() {
    return new IndexPage();
  };

}());

I can run this test hundreds times FF e Chrome, right now i got very very few occurrences of the following in FF:

[launcher] Running 2 instances of WebDriver
...
------------------------------------
[chrome #2] PID: 51569
[chrome #2] Specs: /test/temp.spec.js
[chrome #2]
[chrome #2] Using the selenium server at http://localhost:4444/wd/hub
[chrome #2] Sign Up + Login
[chrome #2]   correct signup - pass
[chrome #2]   correct login - pass
[chrome #2]
[chrome #2]
[chrome #2] Finished in 16.196 seconds
[chrome #2] 2 tests, 2 assertions, 0 failures
[chrome #2]

[launcher] 1 instance(s) of WebDriver still running
F
------------------------------------
[firefox #1] PID: 51568
[firefox #1] Specs: /test/temp.spec.js
[firefox #1]
[firefox #1] Using the selenium server at http://localhost:4444/wd/hub
[firefox #1] Sign Up + Login
[firefox #1]   correct signup - pass
[firefox #1]   correct login - fail
[firefox #1]
[firefox #1]
[firefox #1] Failures:
[firefox #1]
[firefox #1]   1) Sign Up + Login correct login
[firefox #1]    Message:
[firefox #1]      Expected false to be truthy.
[firefox #1]    Stacktrace:
[firefox #1]      Error: Failed expectation
[firefox #1]     at [object Object].fillLoginForm (/test/page_object/index.js:145:56)
[firefox #1]     at [object Object].<anonymous> (/test/temp.spec.js:24:10)
[firefox #1]
[firefox #1]   2) Sign Up + Login correct login
[firefox #1]    Message:
[firefox #1]      Error: redirection after login not performed
[firefox #1] Wait timed out after 7047ms
[firefox #1]    Stacktrace:
[firefox #1]      Error: redirection after login not performed
[firefox #1] Wait timed out after 7047ms
[firefox #1] ==== async task ====
[firefox #1] redirection after login not performed
[firefox #1]     at [object Object].checkRedirection (/test/page_object/index.js:105:22)
[firefox #1]     at [object Object].<anonymous> (/test/temp.spec.js:26:10)
[firefox #1] ==== async task ====
[firefox #1] Asynchronous test function: it()
[firefox #1] Error
[firefox #1]     at [object Object].<anonymous> (/test/temp.spec.js:21:3)
[firefox #1]     at Object.<anonymous> (/test/temp.spec.js:5:1)
[firefox #1]
[firefox #1] Finished in 20.7 seconds
[firefox #1] 2 tests, 3 assertions, 2 failures
[firefox #1]

[launcher] Test runner exited with 2 failed test(s)
[launcher] 0 instance(s) of WebDriver still running
[launcher] firefox #1 failed 2 test(s)
[launcher] chrome #2 passed
[launcher] overall: 2 failed spec(s)
[launcher] Process exited with error code 1
npm ERR! Test failed.  See above for more details.
  1. yes this.getLoginModalUserEmail().clear().sendKeys(email); works for me thx|

  2. i know that IDs should be unique thats also why i planned to refactor HTMLs after having working e2e-tests, this to notice any break in the user functionalities, i dunno if is the right flow
    ideally seems good but roght now im facing problems possibily

@hankduan
Copy link
Contributor

@tundo91 Would you be able to host your app (or the login portion of it) publicly so I can test it, and/or the source code for it. Enough people report it that i feel like it's a real issue, but I cannot reproduce this to determine the nature of the problem.

@enricorotundo
Copy link
Author

Ok @hankduan let's use the staging at https://staging.eversnapapp.com/view, you can create random users using @test.com domain emails.
This is the gist containing my test + page object.
To reproduce the error remove all those .clear() in:

    this.fillSignUpForm = function (name, email, pwd, pwdConfirm) {
      var self = this;

      // fill form
      this.getRegistrationUserName().clear().sendKeys(name);
      this.getRegistrationUserEmail().clear().sendKeys(email);
      this.getRegistrationUserPwd().clear().sendKeys(pwd);
      this.getRegistrationUserPwdConfirm().clear().sendKeys(pwdConfirm);

      // when the register button is enablead means that form is fulfilled
      return browser.wait(function () {
        return self.getRegistrationRegisterButton().isEnabled();
      });
    };

Now run the registration test several times in Chrome and FF.
This is the result:

sendKeys() error

I noticed that seems happening just with the first text input. I've same problem in the login form.

@hankduan
Copy link
Contributor

This is great, thanks! I'll play with this tonight or tomorrow and let you know what I find (or whether I can reproduce it)

@enricorotundo
Copy link
Author

Great waiting for you ✌️
Let me know if you need further info.

@hankduan
Copy link
Contributor

While I haven't been able to reproduce yet, here are some observations I've made on your app (just so I know we're not doing something completely different).

  1. the css selectors you provided don't work. Instead I've changed them to:
  this.getNavBarRegistrationButton = function () {
    return element(by.css('.navbar .pull-right .signup-button'));
  };

  this.getRegistrationRegisterButton = function () {
    return element(by.css('#registrationModalView.modal .modal-footer .btn-primary'));
  };

(maybe you're testing a newer version or something?)

  1. Does the app you're testing contain a bunch of infinite timeouts? -- Protractor gets stuck waiting for angular to be done unless I set browser.ignoreSynchronization = true;, which is the case if you have timeouts in your app.

  2. Does the library you're using (to generate -- open/close -- the modal) have a small timeout-based animation in it (i.e. 2ms)?

My suspicion on why the sendKeys aren't being sent is related to 3 -- if the modal have a small timeout-based animation in it, protractor's sendkeys won't actually send the keys until the timeout is over. What the clear did was just add a little delay.

Try this: instead of adding clear like

      this.getRegistrationUserName().clear().sendKeys(name);
      this.getRegistrationUserEmail().clear().sendKeys(email);
      this.getRegistrationUserPwd().clear().sendKeys(pwd);
      this.getRegistrationUserPwdConfirm().clear().sendKeys(pwdConfirm);

do this:

      //Add some delays here
      this.getRegistrationUserName().sendKeys(name);
      this.getRegistrationUserEmail().sendKeys(email);
      this.getRegistrationUserPwd().sendKeys(pwd);
      this.getRegistrationUserPwdConfirm().sendKeys(pwdConfirm);

like this:

      browser.driver.sleep(2000);
      this.getRegistrationUserName().sendKeys(name);
      this.getRegistrationUserEmail().sendKeys(email);
      this.getRegistrationUserPwd().sendKeys(pwd);
      this.getRegistrationUserPwdConfirm().sendKeys(pwdConfirm);

or this:

      this.getRegistrationUserName().getOuterHtml().then(function() {
        this.getRegistrationUserName().sendKeys(name);
        this.getRegistrationUserEmail().sendKeys(email);
        this.getRegistrationUserPwd().sendKeys(pwd);
        this.getRegistrationUserPwdConfirm().sendKeys(pwdConfirm);
      })

@enricorotundo
Copy link
Author

  1. i'm so sorry i forgot to deploy my local commits. Now should be fine. https://staging.eversnapapp.com/view

  2. before testing i changed all the $timeout calls to $interval and then destroy all intervals objects (included in (1)).

  3. im not sure about the library im gonna check it. Anyway also with a 2000ms delay FF still has the problem. See the screenshot, Chrome runs fine, FF nope. Do you think is still the modal opening? Should be the delay related with the text input?

sendKeysError2

@hankduan
Copy link
Contributor

Ok, I'll test tomorrow with your new version

@hankduan
Copy link
Contributor

I can reproduce this =) That's a great first step -- like you said, chrome is fine; the problem produces itself in firefox.

Now let me go try to see what's going on.

@hankduan hankduan self-assigned this Nov 18, 2014
@hankduan
Copy link
Contributor

@tundo91 This looks like an issue with webdriver/firefox (and perhaps how it's interacting with your page)

Here's a raw webdriver test which exhibit the same behavior:

var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
   usingServer('http://localhost:4444/wd/hub').
   withCapabilities(webdriver.Capabilities.firefox()).
   build();

driver.get('https://staging.eversnapapp.com/view');
driver.findElement(webdriver.By.css('.navbar #sign-up-navbar > #navbar-registration-button')).click();
driver.wait(function() {
 return driver.findElement(webdriver.By.css('#registrationModalView.modal')).isDisplayed();
});

driver.findElement(webdriver.By.css('#registrationModalView.modal form[name="regForm"] #input_last_name')).sendKeys('A user');
driver.findElement(webdriver.By.css('#registrationModalView.modal form[name="regForm"] #input_email')).sendKeys('auser@test.com');
driver.findElement(webdriver.By.css('#registrationModalView.modal form[name="regForm"] #input_password')).sendKeys('123456');
driver.findElement(webdriver.By.css('#registrationModalView.modal form[name="regForm"] #input_confirm_password')).sendKeys('123456');
driver.wait(function() {
 return driver.findElement(webdriver.By.css('#registrationModalView.modal #registrationModal form[name="regForm"] .modal-footer > #modal-register-button')).isEnabled();
});

driver.quit();

So the issue isn't with animation as I had original suspected, but with focus. I want to confirm with you to see if this is the behavior you see, but here's what I noticed: Basically I noticed during the test, as soon as webdriver opens up your app, the focus is on the url bar, until after the first sendKeys.
So doing sendkeys twice on the first field will work (but probably not what you want to do), doing a clear before sendKeys will work, and doing a click() before sendkeys will work. In addition, if you manually click on the webpage the moment the browser comes up before any test is ran (to take the focus away from the url bar) your test should also pass.

Is it okay if I open an issue with webdriver using your app as an example?

@enricorotundo
Copy link
Author

Confirmed:

  • same focusing behaviour (i.e., the focus is on the url bar, until after the first sendKeys).
  • if i click on the webpage the moment the browser comes up my test passes.

@hankduan go ahead with the webdriver issue. Should this being closed?

@hankduan
Copy link
Contributor

No let's keep it open so it's searchable. I feel like there are a few reports of this problem.
The other thing is that if you're actively developing your app, is it possible to save the current version of it somewhere just so that the selectors don't break when they investigate? (I have no idea what their turnaround time is).

@hankduan
Copy link
Contributor

@hankduan hankduan changed the title sendKeys(string) sometimes execute but doesn't insert the text sendKeys() doesn't insert text because focus is on the address bar (firefox only) Dec 11, 2014
@hankduan hankduan removed their assignment Dec 22, 2014
@hankduan
Copy link
Contributor

@tundo91 Can you bring up the staging app at 'https://staging.eversnapapp.com/view' again (or let me know where it has moved to)? Webdriver just started looking at the issue, and it would be helpful if it is up again.

@enricorotundo
Copy link
Author

I'm sorry but I'm not longer in that project i cannot do it :(

@hankduan
Copy link
Contributor

I'm going to close this issue since I haven't seen any other reproducible reports of this, and I cannot provide a reproducible example to selenium.

@grese
Copy link

grese commented Apr 13, 2017

I'm experiencing this exact same behavior on Firefox 52.

@koventhan123
Copy link

i am not able to enter value in Text box field using sendKeys in Safari browser of appium. Any solutions ?

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

5 participants