Robot Framework and SharePoint authentication

When you test a big project, sooner or later will encounter problems with test isolation. Sometimes, to check a particular function or a feature, you have to perform a lot of steps that you have already implemented in another test cases. It tempts you to make those tests dependent on each other or to execute all those clicks in one, complicated test case. Both approaches have significant disadvantages – hard maintenance or long execution time and bug vulnerability. In most of the situations, you can avoid boilerplate code and get your test isolated using API.

REST API

SharePoint REST API allows you to do most of the CRUD operations against the SharePoint server. Of course, you can’t send a request to the server and get the effect without authentication. I’m going to guide you through the process of authentication, and I will show you how to get and create data in the SharePoint list.

SharePoint App registration

We could authenticate with user credentials, but the registered app gives better permission control. So let’s start with the registration.

  1. Go to the site you would like to access from your test case,
  2. Add /_layouts/15/appregnew.aspx to the end of the site URL:
  3. https://contoso.sharepoint.com/sites/foo/_layouts/15/appregnew.aspx
  4. Generate Client Id and Client Secret and fill in the title. You can enter ‘localhost’ in the app domain field and redirect URL box.
  1. Write down the app id and secret. You will need it later.
  2. Go to https://contoso.sharepoint.com/sites/foo/_layouts/15/appinv.aspx
  3. Lookup for your app id. Paste the permission XML. In this example, we will access a list. So paste the following XML and click OK. Be aware that the following XML grants full control permission. You can change it to “manage” or “read”. Check the permissions cheat sheet for more details.
<AppPermissionRequests AllowAppOnlyPolicy="true">
  <AppPermissionRequest scope="http://sharepoint/content/sitecollection/web/list"
   Right="FullControl" />
</AppPermissionRequests>
  1. From the dropdown, select a list that you want to access and trust the application.

The application is ready to use. We need to get only two more things to send an authentication request:

  • tenant name – you can get it from the URL: https://constos.sharepoint.com
  • tenant id – go to portal.azure.com and login with the same credentials you use to log in to the SharePoint. Go to the Properties in Azure Active Directory. Copy Directory ID, which is the id of your tenant.

Let’s code!

First of all, install the requests library:

pip install -U requests
pip install -U robotframework-requests
*** Keywords ***
Get SharePoint OAuth2 Access Token
    [Arguments]                         ${clientId}         ${clientSecret}     ${tenantId}     ${tenantName}
    ${head}=                            Create Dictionary   Accept              application/json;odata\=verbose
    Set To Dictionary                   ${head}             Content-type        application/x-www-form-urlencoded    
    
    ${body}=                            Create Dictionary   grant_type          client_credentials
    Set To Dictionary                   ${body}             client_id           ${clientId}@${tenantId}
    Set To Dictionary                   ${body}             client_secret       ${clientSecret}
    Set To Dictionary                   ${body}             resource            00000003-0000-0ff1-ce00-000000000000/${tenantName}.sharepoint.com@${tenantId}

    Create Session                      auth                https://accounts.accesscontrol.windows.net      verify=${true}
    ${resp}=                            Post Request        auth                /${TENANT_NAME}.onmicrosoft.com/tokens/OAuth/2    headers=${head}   data=${body}
    Dictionary Should Contain Key       ${resp.json()}      access_token
    [Return]                            ${resp.json()["access_token"]}

This keyword takes four arguments you collected in the previous steps. It creates a header dictionary, then goes to a body that contains all properties required for authentication:

  • client_id – SharePoint app ID and tenant ID joined with @ symbol,
  • clinet_secret – SharePoint app secret,
  • grant_type – containing a constant string: ‘client_credentials’,
  • resource – starting with constant GUID 00000003-0000-0ff1-ce00-000000000000, then after a slash goes SharePoint URL and once again @ symbol and the tenant ID.

We create a session with requests library keyword and arguments:

  • Alias to identify the session,
  • Server base URL,
  • SSL verification.

Then, we perform POST request and return OAuth 2.0 access token. We can use this token to get a list item or create a new one.

Get List Item
    [Arguments]                         ${webUrl}           ${listName}         ${itemId}       ${accesToken}
    ${head}=                            Create Dictionary   Accept=application/json;odata\=nometadata       Authorization=Bearer ${accesToken}

    Create Session                      getElement          ${webUrl}           verify=${true}
    ${resp}=                            Get Request         getElement          /_api/web/lists/GetByTitle('${listName}')/Items(${itemId})  headers=${head}
    [Return]                            ${resp.json()}

Create List Item
    #{item} is a dictionary with list fields and their value
    [Arguments]                         ${webUrl}           ${listName}         ${item}         ${accessToken}
    ${head}=                            Create Dictionary   Accept=application/json;odata\=nometadata       Authorization=Bearer ${accessToken}          Content-Type=application/json;odata\=nometadata
    
    Create Session                      createElement       ${webUrl}           verify=${true}
    ${resp}=                            Post Request        createElement       /_api/web/lists/GetByTitle('${listName}')/Items    headers=${head}   data=${item}
    [Return]                            ${resp.json()}

If you want to create a list item, you have to create a dictionary containing field-name and field-value pairs.

${item}=                            Create Dictionary   Title               My new item
Set To Dictionary                   ${item}             Description         This item was created by RF.
Create List Item                    ${webUrl}           TestData            ${item}        ${accessToken}

Now, you can use those keywords to access SharePoint API. Use it to set up your solution before each test case and keep your tests independent!