fbpx
Uncategorized

How To Create An Automated Login Page Test And Use Multiple Credentials

Countless things should be tested within web applications but among them, one of the most important scenarios to be tested and even load tested is the user login process. User login serves as a medium between providing users with most of the product features and therefore requires careful and thorough testing. If your website allows users to log in, a login page test is necessary. An automated test for this can be easily created for this. In addition you can scale it up to validate that the login process works perfectly under a high load too.

When the product reaches a certain user base it is highly recommended to load test the service. A lot of different issues can pop-out regarding usability, performance, and service stability. This case is extremely relevant for services that can see bursts of logins in short timeframes, such as ticket resellers starting to sell tickets to a concert. Leaving this scenario untested can negatively impact service success. In other words, being unable to log in can deter potential customers from choosing your service in favor of a different one. In this blog post, we will be focusing on designing a load test for login functionality. We will also show two ways of using multiple credentials in the test. 

Login test data preparation

For the actual test, we will need to have login credentials containing email and password. These credentials will be provided for the web application sign-in form. As such there are multiple ways how we can make use of them. We will be taking a look at 2 possible scenarios of saving and utilizing them. Examples in this blog post will be written using Nightwatch+Javascript programming language, but all of these examples can easily be replicated using TestUI+Java language as well. If you are new to using Nightwatch, here is a beginner’s guide on writing a test script in Nightwatch+Javascript.

Using hardcoded credentials

First of all, we can hardcode some user emails and passwords at the top of the test script for easier manipulation. For this, we will create an array of containing objects – each consisting of email and password fields. Each object can be counted as a single login credential pair. The downside of using this approach is that these credentials are not located in a secured place, but are rather hardcoded in the script and can easily be accessed by other project members.

client => {
    // Define credentials for 3 different participants.
    const credentials = [
        {email: 'example1@bing.com', password: 'password123'},
        {email: 'mock@google.com', password: 'TestPassword1'},
        {email: 'laugh@yahoo.com', password: '1PasswordTest'}
    ];
    // Retrieve single participant credentials.
    const partCredentials = credentials[client.globals.participant.id];
    // Rest of the test script will go here.
}

Using externally hosted credentials

There is a possibility when single credentials will not be enough and we would like to have, for example, 100 dynamic unique credential pairs for your login page test. The most common way to handle this is to host credentials externally and retrieve them using API requests. The downside of this method is that credentials need to be hosted somewhere, like in the AWS S3 bucket. After retrieving necessary credentials we can map them in an array of objects where each object would contain email and password. This also means that API should return JSON response in the format similar to the one seen in the first example, e.g., an array of objects with email and password keys.

When these credentials are retrieved and saved into a variable within the script, we can retrieve a pair using unique internal Loadero participant IDs (NightWatch+Javascript and TestUI+Java) and pass them into the sign-in form. In general, the response format can be arbitrary – list of objects, list of usernames with a common password, etc. Example JSON response:

[
    {
        "email": "example1@bing.com",
        "password": "password123"
    },
    {
        "email": "mock@google.com",
        "password": "TestPassword1"
    },
    {
        "email": "laugh@yahoo.com",
        "password": "1PasswordTest"
    }
]

Tip: We recommend retrieving these credentials in a secure way, e.g., providing a one-time access token in the request header. This ensures that your data won’t be easily captured and ensures your or your client’s security. To do so, see your external service provider documentation.

client =>  {
    // Define a variable which will contain participant credentials.
    let participantCredentials = {};
    const loadCredentials = (client, done) => {
        // Calling request to retrieve data from https://example.com/credentials url
        request(
            { url: 'https://example.com/credentials' },
            (error, response, body) => {
                // If error was encountered this will stop test execution for particular participant.
                if (error) throw new Error(error);
                // Parsing received data into our credentials variable.
                const credentials = JSON.parse(body);
                // Retrieving single participant credentials based on unique internal Loadero variables.
                participantCredentials = credentials[client.globals.participant.id];
                // Calling done callback function signaling that this function has finished retrieving data and test script can continue.
                done();
            }
        );
    }
    // Requesting credentials from external source, parsing response and saving participant credentials variable.
    client.perform(done => loadCredentials(client, done));
    // Now we can access credentials for this participant using `participantCredentials.email` and `participantCredentials.password`
}

Loadero test and participant setup

Now that we have gotten basic data preparation covered we can move on to setting up a login page test within Loadero. If you are new to Loadero, here is a step-by-step guide to creating a test. For simplicity we will use the hardcoded credentials approach in this example. You can create a similar test using externally hosted credentials as well, the difference will be only in the script. To start it all up go to one of your account prepared projects and press the `New Test` button. 

Configuring a login page test with hardcoded credentials

We will be creating a test using these parameters:

  • Title: Login test
  • Test mode: Performance test
  • Increment strategy: Linear participant
  • Start interval: 1s
  • Participant timeout: 1min
  • Script:
client => {
    // Define login page URL to be used in the script later on.
    const logInPage = 'https://github.com/login';
    // Define credentials for 3 different participants.
    const credentials = [
        {email: 'example1@bing.com', password: 'password123'},
        {email: 'mock@google.com', password: 'TestPassword1'},
        {email: 'laugh@yahoo.com', password: '1PasswordTest'}
    ];
    // Define max acceptable wait time for element to become visible.
    const waitTimeout = 10 * 1000;
    // Select participant credentials from the hardcoded credential list.
    const partCredentials = credentials[client.globals.participant.id];
    client
        // Navigate to the login page.
        .url(logInPage)
        // Wait for the page body to load in.
        .waitForElementVisible('body', waitTimeout)
        // Take a screenshot of the sign-in form.
        .takeScreenshot('logInPage.png')
        // Fill in the email field in the sign-in form.
        .setValue('#login_field', partCredentials.email)
        // Fill in the password field in the sign-in form.
        .setValue('#password', partCredentials.password)
        // Take a screenshot with filled in sign-in form fields.
        .takeScreenshot('formFilled.png')
        // Click the login button.
        .click('.js-sign-in-button')
        // Wait until the main page has been loaded after user authentication.
        .waitForElementVisible('.AppHeader-user', waitTimeout)
        // Take a screenshot of the authenticated user on the main page.
        .takeScreenshot('loggedIn.png');
}

Now, that we have created this test, let’s create 1 participant group for this example. Create it with the title set to “Test group” and count set to 1. 

Test group creation

We will create one participant in the group and set its count to 3. So we will have three test participants with identical configurations. Each of them will use different credentials in the test run. 

Participant parameters:

  • Title: Participant
  • Count: 3
  • Compute units: G1
  • Browser: Latest Google Chrome
  • Location: US West – Oregon
  • Network conditions: Default network settings
  • Media: Built-in Video + Audio feed
Test participant configuration

Now we have everything ready to run a test to validate login process functionality. The test will take screenshots in 3 phases of the test: opened login form, login form with entered credentials, and projects view once the user has logged in. For more in-depth test report explanations you can check out this blog post.

Load testing login process

As mentioned before there are cases where you should test a login page in increased load capacity. For these cases, we would suggest using the 2nd way of preparing data for the test. As for the process itself, it would be some simple adjustments. In the previously described example the test participants finish the test once the page is loaded after logging in and a screenshot is taken. To generate load on the login process we need to create a loop where the test participant opens the login page, does the authentication, and then just logs out of the service. The test run will continue until all the participants perform these actions for a set number of times.  

Important: Always limit how many times the loop will be executed, otherwise it may result in an infinite loop, which may result in participant timeout and unpredictable load on the website.

Here is an example script for a login process load test in which every participant will log in and log out for 15 times:

client => {
    // Initialize variable for maximum wait time spent loading page/element
    const loadTimeout = 30 * 1000;
    // Number of times to navigate through the page
    let iterations = 15;
    // Define login page URL to be used in the script later on.
    const logInPage = 'https://github.com/login';
    // Define a variable which will contain participant credentials.
    let participantCredentials = {};
    const loadCredentials = (client, done) => {
        // Calling request to retrieve data from https://example.com/credentials url
        request(
            { url: 'https://example.com/credentials' },
            (error, response, body) => {
                // If error was encountered this will stop test execution for particular participant.
                if (error) throw new Error(error);
                // Parsing received data into our credentials variable.
                const credentials = JSON.parse(body);
                // Retrieving single participant credentials based on unique internal Loadero variables.
                participantCredentials = credentials[client.globals.participant.id];
                // Calling done callback function signaling that this function has finished retrieving data and test script can continue.
                done();
            }
        );
    }
    // Requesting credentials from external source, parsing response and saving participant credentials variable.
    client.perform((client, done) => loadCredentials(client, done));
    client.perform(() => {
        // Loops while specified iteration count has been reached
        while (iterations) {
            client
                // Navigate to the login page.
                .url(logInPage)
                // Wait for the page body to load in.
                .waitForElementVisible('body', loadTimeout)
                // Fill in the email field in the sign-in form.
                .setValue('#login_field', participantCredentials.email)
                // Fill in the password field in the sign-in form.
                .setValue('#password', participantCredentials.password)
                // Click login button.
                .click('.js-sign-in-button')
                // Wait until the projects page has been loaded after user authentication.
                .waitForElementVisible('.AppHeader-user', loadTimeout)
                // Click on the user icon
                .click('.AppHeader-user')
                // Click on the Sign out button
                .click('a[href="/logout"]')
                // Wait for the page body to load in.
                .waitForElementVisible('body', loadTimeout);
            // Reduces remaining iteration count by 1
            iterations--;
        }
    });
}
Configuring a login page load test with externally hosted credentials

We have to update the test to load test mode and alter the start interval and participant timeout fields accordingly. In this example we will have 50 participants, the start interval of 50 seconds, and participant timeout of 5 minutes. This means 1 participant per second will be joining.

load test virtual participant

One more thing that we need to adjust is the participant count. To change that up, just open the test participant page and change the participant count field to a desirable result. You can read more about transforming your performance test to a load test here. 100 compute units included in the Loadero free trial plan, you can launch a test like we have in the example twice free of charge.

Conclusions

If your website or web application allows users to login, make sure you have tested this process. In addition we recommend relaunching the test after application updates. Load testing the process is no less important and should be done when you reach a significant number of users. Do it before an expected traffic increase due to the marketing efforts, seasonality, or if spikes of traffic are in the nature of your business. We also highly recommend running login process load tests regularly to always be sure application is ready to handle many users logging in concurrently. With your user count increasing, you should also consider scaling up your load tests accordingly. 

With tests created in Loadero, rerunning them and validating your application is ready to serve hundreds or thousands of users logging in is a matter of minutes and just some clicks. Start creating your tests now by signing up for a free trial account and don’t hesitate to contact our helpful support team if you have questions.