Search code examples
angularjscasperjs

How to use CasperJS to fill in AngularJS input fields w/out a form tag


I'm trying to write a CasperJS script which does a login at https://frontier.com/login.

I'm having trouble because:

  1. it uses AngularJS so it seems I can't access and change the values held in its scope (eg. ng-model='login.loginId'). Setting the values directly on the elements doesn't have any effect.

  2. the input fields are not wrapped with a form element so using the usual fillSelectors() with CasperJS isn't possible

  3. casper.exists('input#fid-login-inline-username') returns true, but, casper.sendKeys('input#fid-login-inline-username', 'blah') gives an error saying [error] [remote] mouseEvent(): Couldn't find any element matching 'input#fid-login-inline-username' selector

The fields to work with are:

  1. input#fid-login-inline-username
  2. input#fid-login-inline-password
  3. div.login-form-container button.btn-primary - for click()

So, how do I edit the two input fields from casper into the angular scope?

Here is an example of what I've tried:

casper.start('https://frontier.com/login', function() {
  this.echo('waiting for password input field');
  this.waitForSelector("input#fid-login-inline-password");
});

casper.then(function() {
  if (this.exists('input#fid-login-inline-username')) {
    this.echo('username input exists');
  }
  if (this.exists('input#fid-login-inline-password')) {
    this.echo('password input exists');
  }
  this.echo('filling in username and password');
  // these fields are not in a form element, so, use sendKeys to enter text...
  // the above echoes print the fields exist, and then these sendKeys 
  // operations emit an error that the fields don't exist.
  this.sendKeys('input#fid-login-inline-username', '[email protected]');
  this.sendKeys('input#fid-login-inline-password', 'some-password');
});

casper.then(function() {
  this.echo('clicking login button');
  this.click('div.login-form-container button.btn-primary');
});

Solution

  • I figured it out. The app is creating two input elements per ID. If I get the second one then I can set the value and trigger an event for AngularJS to see it.

    function login(un, pw) {
      $($('[ng-model="login.loginId"]')[1]).val(un).trigger('input');
      $($('[ng-model="login.password"]')[1]).val(pw).trigger('input');
    };
    this.evaluate(login, username, password);