5

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','xxxxxxxx@xxxx.com') 
    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','salvador.salvatierra@alegra.com')
    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','xxxxxxxx@xxx.com') 
    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();          
    });
});
iamdanchiv
  • 3,828
  • 4
  • 32
  • 40

1 Answers1

7

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','xxxxxxxxxxx@xxxx.com') 
                .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','xxxxxxxxxxx@xxxx.com') 
                .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!

iamdanchiv
  • 3,828
  • 4
  • 32
  • 40
  • i have a small suit, with more than 30 files, every file have the setValue('#email') and setValue('#password')to loging in first place into the system. What i have in mind is to used some cookies, erase this setValue and instead put the setCookie, or do it via console like:./node_modules/.bin/wdio wdio.conf.js --spec create_contact.js --sessionID ZXVZXCVZFASDFASDFASDFASDF, can I do something like that? – Salvador Salvatierra Jun 12 '17 at 17:11
  • Let me be more specific, I have a "suite" divide in modules (invoice, contact, payment), every module have like 10 files to test every thing inside each module and each file have a "describe" with some "it" inside it. Every file in each module pass through login. I want is to erase that, what I want is when i run a single file, the module or all the "suite" somehow the first file to execute look the credential so i dont waste time going through login in every file and instead of that go direct to ex: using browser.url('www.someurl.com'), do you know what i mean? – Salvador Salvatierra Jun 13 '17 at 03:16
  • Abour login with different account, it could be depends where you run the test – Salvador Salvatierra Jun 13 '17 at 03:37
  • hey i had try the update and it works partially, this is the way, want i dont know now is how can i check if there is a created cookies before the login part? if there is a cookies, it should not do the login part, if there isn't should do the login part and create a cookie for the next suite just read the cookie and avoid do the login, I dont know if it clear for you? – Salvador Salvatierra Jun 15 '17 at 14:13
  • I dont get it clear, if i have two files for example, i want to used what you told me in the beforeSuite when the first file get execute but what i want is when the second file get execute, do not pass throw the login again, like i understand the beforeSuite is going to execute everytime a suite is going on, right? – Salvador Salvatierra Jun 15 '17 at 14:51
  • Yes, i already read it, thanks for that, each file is a suite, I mean each file have just 1 describe inside it, I was thinking that, to move it to a single file, but the practice talk about separate each describe and put it each in a different file, thats why i'm doing this, what i was thinking is to make inside beforeSuite is some kind of ifelse statement where in the if search about if there is some cookie, if there is not, go to the else, login and create a cookie – Salvador Salvatierra Jun 15 '17 at 15:06
  • I have another question, when the webdriver close the session, it will delete all cookies created in that session? – Salvador Salvatierra Jun 15 '17 at 17:10
  • hey men I have a new issue https://stackoverflow.com/questions/44877856/how-to-use-selenium-webdriver-io-to-search-some-action-button-in-an-index-list – Salvador Salvatierra Jul 03 '17 at 19:08
  • Great men @iamdanchiv – Salvador Salvatierra Jul 10 '17 at 01:08