Skip to content

Commit 93ccbb7

Browse files
authored
Merge pull request #227241 from salman90/adding-tests-with-JavaScript
Add test example for MSAL.js
2 parents fe630d9 + 8ab22d1 commit 93ccbb7

File tree

1 file changed

+114
-1
lines changed

1 file changed

+114
-1
lines changed

articles/active-directory/develop/test-automate-integration-testing.md

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,11 @@ To exclude a test application:
122122

123123
## Write your application tests
124124

125-
Now that you're set up, you can write your automated tests. The following .NET example code uses [Microsoft Authentication Library (MSAL)](msal-overview.md) and [xUnit](https://xunit.net/), a common testing framework.
125+
Now that you're set up, you can write your automated tests. The following are tests for:
126+
1. .NET example code uses [Microsoft Authentication Library (MSAL)](msal-overview.md) and [xUnit](https://xunit.net/), a common testing framework.
127+
1. JavaScript example code uses [Microsoft Authentication Library (MSAL)](msal-overview.md) and [Playwright](https://playwright.dev/), a common testing framework.
128+
129+
## [.NET](#tab/dotnet)
126130

127131
### Set up your appsettings.json file
128132

@@ -252,3 +256,112 @@ public class ApiTests : IClassFixture<ClientFixture>
252256
}
253257
}
254258
```
259+
260+
## [JavaScript](#tab/JavaScript)
261+
262+
### Set up your authConfig.json file
263+
264+
Add the client ID and the tenant ID of the test app you previously created, the key vault URI and the secret name to the authConfig.js file of your test project.
265+
266+
```javascript
267+
export const msalConfig = {
268+
auth: {
269+
clientId: 'Enter_the_Application_Id_Here',
270+
authority: 'https://login.microsoftonline.com/Enter_the_Tenant_Id_Here',
271+
},
272+
};
273+
274+
export const keyVaultConfig = {
275+
keyVaultUri: 'https://<your-unique-keyvault-name>.vault.azure.net',
276+
secretName: 'Enter_the_Secret_Name',
277+
};
278+
```
279+
280+
### Initialize MSAL.js and fetch the user credentials from Key Vault
281+
282+
Initialize the MSAL.js authentication context by instantiating a [PublicClientApplication](https://azuread.github.io/microsoft-authentication-library-for-js/ref/classes/_azure_msal_browser.publicclientapplication.html) with a [Configuration](https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal.html#configuration) object. The minimum required configuration property is the `clientID` of the application.
283+
284+
Use [SecretClient()](/javascript/api/@azure/keyvault-secrets/secretclient) to get the test username and password secrets from Azure Key Vault.
285+
286+
[DefaultAzureCredential()](/javascript/api/@azure/identity/defaultazurecredential) authenticates with Azure Key Vault by getting an access token from a service principal configured by environment variables or a managed identity (if the code is running on an Azure resource with a managed identity). If the code is running locally, `DefaultAzureCredential` uses the local user's credentials. Read more in the [Azure Identity client library](/javascript/api/@azure/identity/defaultazurecredential) content.
287+
288+
Use Microsoft Authentication Library (MSAL) to authenticate using the ROPC flow and get an access token. The access token is passed along as a bearer token in the HTTP request.
289+
290+
291+
```javascript
292+
import { test, expect } from '@playwright/test';
293+
import { DefaultAzureCredential } from '@azure/identity';
294+
import { SecretClient } from '@azure/keyvault-secrets';
295+
import { PublicClientApplication, CacheKVStore } from '@azure/msal-node';
296+
import { msalConfig, keyVaultConfig } from '../authConfig';
297+
298+
let tokenCache;
299+
const KVUri = keyVaultConfig.keyVaultUri;
300+
const secretName = keyVaultConfig.secretName;
301+
302+
async function getCredentials() {
303+
try {
304+
const credential = new DefaultAzureCredential();
305+
const secretClient = new SecretClient(KVUri, credential);
306+
const secret = await secretClient.getSecret(keyVaultConfig.secretName);
307+
const password = secret.value;
308+
return [secretName, password];
309+
} catch (error) {
310+
console.log(error);
311+
}
312+
}
313+
314+
test.beforeAll(async () => {
315+
const pca = new PublicClientApplication(msalConfig);
316+
const [username, password] = await getCredentials();
317+
const usernamePasswordRequest = {
318+
scopes: ['user.read', 'User.ReadBasic.All'],
319+
username: username,
320+
password: password,
321+
};
322+
await pca.acquireTokenByUsernamePassword(usernamePasswordRequest);
323+
tokenCache = pca.getTokenCache().getKVStore();
324+
});
325+
```
326+
327+
### Run the test suite
328+
329+
In the same file, add the tests as shown below:
330+
331+
```javascript
332+
/**
333+
* Stores the token in the session storage and reloads the page
334+
*/
335+
async function setSessionStorage(page, tokens) {
336+
const cacheKeys = Object.keys(tokens);
337+
for (let key of cacheKeys) {
338+
const value = JSON.stringify(tokenCache[key]);
339+
await page.context().addInitScript(
340+
(arr) => {
341+
window.sessionStorage.setItem(arr[0], arr[1]);
342+
},
343+
[key, value]
344+
);
345+
}
346+
await page.reload();
347+
}
348+
349+
test.describe('Testing Authentication with MSAL.js ', () => {
350+
test('Test user has signed in successfully', async ({ page }) => {
351+
await page.goto('http://localhost:<port>/');
352+
let signInButton = page.getByRole('button', { name: /Sign In/i });
353+
let signOutButton = page.getByRole('button', { name: /Sign Out/i });
354+
let welcomeDev = page.getByTestId('WelcomeMessage');
355+
expect(await signInButton.count()).toBeGreaterThan(0);
356+
expect(await signOutButton.count()).toBeLessThanOrEqual(0);
357+
expect(await welcomeDev.innerHTML()).toEqual('Please sign-in to see your profile and read your mails');
358+
await setSessionStorage(page, tokenCache);
359+
expect(await signInButton.count()).toBeLessThanOrEqual(0);
360+
expect(await signOutButton.count()).toBeGreaterThan(0);
361+
expect(await welcomeDev.innerHTML()).toContain(`Welcome`);
362+
});
363+
});
364+
365+
```
366+
367+
For more information, please check the following code sample [MSAL.js Testing Example](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/msal-browser-samples/TestingSample).

0 commit comments

Comments
 (0)