1

I am using the Intern for my functional tests. One such test requires being logged into an admin account:

registerSuite({
    name: 'login',

    'login': function() {
        return this.remote
            .get(URL)
            .findById('username')
                .click()
                .pressKeys(USER.ADMIN.USERNAME)
                .end()
            .findById('password')
                .click()
                .pressKeys(USER.ADMIN.PASSWORD)
                .pressKeys('\n')
                .end()
            .findByCssSelector('.login-welcome')
                .getVisibleText()
            .then(function(text) {
                assert.strictEqual(text, USER.ADMIN.NAME, 'User should now be logged in');
            });
    }
});

Now, the problem is that this password is passed in as plain text. Here it is being displayed on BrowserStack:

00:19 | 0 | Send a sequence of key strokes to the active element. | password

It's the same on SauceLabs:

COMMAND: POST keys
PARAMETERS: {"value":["password"]}

The problem lies in the fact that access to these tests aren't restricted--these tests need to be viewed by people in other departments.

Even without that, on the off chance that the password to the testing account is compromised, I don't want the attacker to suddenly get admin access to everything else.

Is there any way to make it so that the password isn't stored / shown as plain text in the commands?

My team is currently entertaining the idea of running a separate script to activate / deactivate these accounts so that they only work while running the functional tests, but I wanted to see if anyone has come up with a better solution.

jperezov
  • 3,041
  • 1
  • 20
  • 36

2 Answers2

2

There isn't a built-in way to hide keystrokes being sent to a remote browser, nor to exclude them from testing framework logs. From the testing framework's perspective, they're just keystrokes, not a password.

Of course, the ideal way to handle this situation would be to use a test deployment of the target application, which would be both safer and allow more control for testing. Assuming that's not possible, though...

One possibility for getting a password into the browser without it being logged is to have the browser load a script via an injected script tag that will fill in the password. Basically, you'd have an external script that would find the password field and enter the value. In the functional test, you'd need to inject a script tag into the browser and then wait for it to load, something like:

return this.remote
    .get(URL)
    .findById('username')
        .click()
        .pressKeys(USER.ADMIN.USERNAME)
        .end()
    .executeAsync(function (done) {
        window._intern_done = done;
        var script = document.createElement('script');
        script.src = '/path/to/password_script.js';
        document.head.appendChild(script);
    })
    .findByCssSelector('.login-welcome')
    // continue testing

The script itself might look like:

(function () {
    // set the password
    var passwordField = document.getElementById('password');
    passwordField.value = 'secret password';
    // clean up the _intern_done global we set in the executeAsync block
    var done = window._intern_done;
    delete window._intern_done;
    // let Intern know we're done
    done();
})();
jason0x43
  • 3,363
  • 1
  • 16
  • 15
  • This looks promising. Is there any way to load a script from the local machine? I.E. `script.src = 'http://localhost/path/to/password_script.js';`. – jperezov Nov 30 '15 at 17:36
0

There is a not listed setting for Browserstack which you can add to your capabilities:

browserstack.maskSendKeys: true

All input will be masked in the logs.

https://github.com/DEFRA/quke/blob/master/.config.example.yml

goatsy
  • 31
  • 2