Automatically Profiling an App secured by OAuth

By Christophe Dujarric, on Mar 01, 2019

The Blackfire Player is a very powerful tool to execute HTTP-based testing scenarios. It is Open-Source, and can be used to automate Blackfire profiling just as well as to execute any other type of scenario within your testing pipeline.

Scripting Basic Login Scenarios with the Player

A rather common use case when having to test an app is to consider a user journey that requires them to login, before executing any other action.

This can be done as below:

scenarios: |
    #!blackfire-player

    name "Login Scenario"

    set user_login "my_login"
    set user_password "my_password"

    scenario
        name 'Basic Login'

        visit url('/login')
            name 'Login page'

        submit button('Log in')
            name 'Submit log in form'
            param _username user_login
            param _password user_password

        follow
            name 'Login redirection'
            expect current_url() == endpoint ~ '/'
            expect body() matches '/Welcome ' ~ user_login ~ '/'

Scripting an OAuth Login Scenario

Let’s have a look at a scenario which we execute in our own test suite; a login via OAuth.

The trick is that instead of having a “/login” page where the user would enter their login and password, they click on a button that redirects them to another site, most probably not managed by the app’s developer (e.g. Google, Facebook, GitHub, …). That’s where they’ll enter their credentials, before coming back to the app.

Here is our way to handle this:

scenarios: |
    #!blackfire-player

    name "BKF Scenarios"

    set user_login "connect_username_to_be_defined"
    set user_password "connect_password_to_be_defined"

    scenario
        name 'Authenticate'

        visit url('/login')
            name 'Login page'
            expect current_url() == endpoint ~ '/login'
            assert metrics.sql.queries.count <= 12

        click link('SymfonyConnect')
            name 'Connect with Symfony Connect'
            blackfire false
            expect current_url() == endpoint ~ '/session/connect/symfony'

        follow
            name 'Follow redirection to Symfony Connect'
            blackfire false
            follow_redirects

        submit button("Sign in")
            name 'Sign in on Symfony Connect'
            blackfire false
            follow_redirects
            param form[_username] user_login
            param form[_password] user_password
            expect current_url() == 'https://connect.symfony.com/secured/login_check'

        click link('Dashboard')
            name 'Dashboard page'
            expect current_url() == endpoint ~ '/dashboard'
            expect status_code() == 200

Let’s have a look at some of the tricks in this scenario:

Passing Credentials as Environment Variables

As we’ll need to use some credentials in the scenario, a safe way is to set some variables, and pass the value via Blackfire environment variables.

    set user_login "connect_username_to_be_defined"
    set user_password "connect_password_to_be_defined"

Environment variables can be defined for a Blackfire environment via the web UI:

Discarding Blackfire Profiling

By default when running our scenario, each PHP request that will be triggered will be profiled (that’s what we’re here for, right?).

However in our OAuth login use case, we’re of course not going to try and profile the OAuth provider’s app. In order to avoid any error responses in our build report, we can ask Blackfire not to try to profile a specific scenario set with `blackfire false`. Example, when we’re on the SymfonyConnect site:

        click link('SymfonyConnect')
            name 'Connect with Symfony Connect'
            blackfire false
            expect current_url() == endpoint ~ '/session/connect/symfony'

        follow
            name 'Follow redirection to Symfony Connect'
            blackfire false
            follow_redirects

We hope you’ll find this useful!

Don’t forget that the Player is Open-Source! Your contributions are welcome for the whole community!

Happy profiling,

Christophe Dujarric

Christophe is the Chief Product Officer at Blackfire. He's an engineer, but probably one of the least "tech" people in the company. He's wearing many hats, from product management to marketing and sales. He loves the beauty of simple solutions that solve actual problems.