Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid re-entering user/email and password with WebDriverIO in login form

I want to optimize my WebdriverIO tests. I'm trying to avoid to re-entering the username & password when I run a test suite with WebdriverIO. (Chromedriver)

The following two files are part of one module, and there are 4 modules in total.

First feature-file:

var name = 'Andrea' + Math.floor((Math.random() * 1000000) + 1);
var ssn = 'V-' + Math.floor((Math.random() * 1000000) + 1);
var url = 'http://someurl.com';
var new_contact = 'https://someurl.com/client/add';

describe('Some contact is create', function() {

  it('Should login to the system', function() { 
    browser.url(url)
    browser.setValue('#email','[email protected]') 
    browser.setValue('#password','xxxxxx') 
    browser.click('#submit');
  });

  it('Should be fill the form', function() {
    browser.url(new_contact)
    browser.waitForVisible('#addClient')
    browser.setValue('#clientNameTextField-inputEl',name)
    browser.setValue('#clientIdentidicationTextField-inputEl',ssn)
    browser.setValue('#clientAddressTextField-inputEl','El busque')
    browser.setValue('#clientCicyyTextField-inputEl','Valencia')
    browser.setValue('#clientEmailField-inputEl','[email protected]')
    browser.setValue('#clientPhoneTextField-inputEl','04141234567')
    browser.setValue('[name="phone2"]','04147654321')       
  });

  it('the contact is store',function() {        
    browser.click('=save)
    browser.waitForExist('#viewClientInfoBalances')
    browser.end;
  });
});

 });

Second feature-file:

var url = 'http://someurl.com';

describe('We get the basic info from index contact', function(){

    it('Shouldlogin to the system', function(){ 
    browser.url(url)
    browser.setValue('#email','[email protected]') 
    browser.setValue('#password','xxxxx') 
    browser.click('#submit');
    });

    it('We should see the basic info', function(){
    browser.click('[href="/client"]')
    browser.click('#gridview-1043-record-ext-record-66 .action-icons a:nth-child(1)')
    browser.waitForExist('#viewClientInfoBalances')
    browser.end();          
    });
});
like image 735
Salvador Salvatierra Avatar asked Jun 12 '17 04:06

Salvador Salvatierra


1 Answers

I see three possible solutions of different approaches:

1. Create a login setup:

Since I see you're using Mocha, then I would go for running your login snippet before all your test-cases in a .before() hook:

describe("StackOverflow Test Suite", function() {

        before(function() {
            return browser
                .url(url);
                .setValue('#email','[email protected]') 
                .setValue('#password','xxxxxxxx') 
                .click('#submit');
        });

        it("\nYour first test...\n", function() {
            return ...
        });

        it("\nYour second test...\n", function() {
            return ...
        });
}); 

Obs: The .before() hook will be run ONLY ONCE, per test-suite. If you have different test-suites (describe statements) in which you need a login for every test-case, then use the .beforeEach() hook.


Update !!! As per Salvador's requirement, in the comment section, this part has been added.

You have two ways to achieve this:

  • Move your Login in the wdio.config.js beforeSuite hook:

    // Hook that gets executed before the suite starts
     beforeSuite: function (suite) {
        return browser
                .url(url);
                .setValue('#email','[email protected]') 
                .setValue('#password','xxxxxxxx') 
                .click('#submit');
     },
    
  • Create a main.js file where you inject all your "modules". You login from that file alone and inject all your describe-populated files via require in it:

Injector:

function importTest(name, path) {
    describe(name, function() {
        require(path);
    });
}

main.js:

describe("All your tests go here!", function () {

    // Executes its content before each imported feature
    beforeEach(function() {
        // beforeHooks
    });

    // Imported features/module files
    importTest('Clients module', '../modules/clients.js');
    //importTest('Devices module', '../modules/devices.js');

    // Executes its content after all features have executed
    after(function () {
        // afterHooks
    });
});

2. Loading a custom profile:

  1. Start your WebdriverIO test case, but add a browser.debug() after you load your page;
  2. Go to your website and LOGIN with your required account. Make sure you save the credentials in the browser;
  3. Now we have to save this custom profile and load it each time you start a WebdriverIO test case. Type chrome://version in your address bar. Notice the Profile Path value. Copy the content of the folder (e.g.: For C:\Users\<yourUserName>\Desktop\scoped_dir18256_17319\Default, copy the scoped_dir18256_17319 folder on your Desktop). This folder contains all the actions (search history, extensions installed, accounts saved/saved credentials in our case) on THIS current instance;
  4. Now all we need to do, is add the path to that folder in your wdio.config.js file as a chromeOptions argument:

    chromeOptions: {
        //extensions: ['./browserPlugins/Avira-SafeSearch-Plus_v1.5.1.crx'],
        args: [ '--user-data-dir=/Users/<yourUserName>/Desktop/scoped_dir18256_17319'
        ]
    }
    

Now all you have to do is run your test cases with this custom profile and you will be logged in with your preferred username/password combination.

Obs: You can read more about Custom Profiles HERE, Use Custom Profile section.


3. Loading the authentication cookies (won't work on all websites)

  1. Login on your website with the required username/password combo;
  2. Open the Chrome console and go to Applications tab, in the Cookies menu;
  3. You will have to identify your authentication token (usually, all websites store information like credentials in cookies);
  4. Add that exact cookie (AFTER YOU LOAD YOUR URL) using the .cookie(), or .setCookie() methods.

Code should look like this:

browser.setCookie({name: '<AuthCookieName>', value: '<AuthToken>'});
browser.refresh();
// Sometimes you have to refresh twice
browser.refresh(); 
// Assert you are logged in

See THIS answer I gave to a similar question as an example.

Hope this helps you. Cheers!

like image 161
iamdanchiv Avatar answered Oct 06 '22 10:10

iamdanchiv