Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion e2e/davinci-suites/src/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ test('Test happy paths on test page', async ({ page }) => {

await page.getByRole('button', { name: 'Sign On' }).click();

await expect(page.getByText('Complete')).toBeVisible();
await expect(async () => await expect(page.getByText('Complete')).toBeVisible()).toPass();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the functional reason for this toPass?


const sessionToken = await page.locator('#sessionToken').innerText();
const authCode = await page.locator('#authCode').innerText();
Expand Down
31 changes: 22 additions & 9 deletions e2e/davinci-suites/src/phone-number-field.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,18 @@ test.describe('Device registration tests', () => {
await page.getByRole('textbox', { name: 'Password' }).fill(password);
await page.getByRole('button', { name: 'Sign On' }).click();

await page.getByRole('button', { name: 'USER_DELETE' }).click();
await expect(page.getByRole('heading', { name: 'Success' })).toBeVisible();
/**
* This implements a retry automatically on a timeout
* because this code path is not critical to the functionality
* we should consider this pattern because its flakey.
*
*/
await expect(
async () => await page.getByRole('button', { name: 'USER_DELETE' }).click(),
).toPass();
expect(
async () => await expect(page.getByRole('heading', { name: 'Success' })).toBeVisible(),
).toPass();
});

test('Login - add email device - authenticate with email device', async ({ page }) => {
Expand All @@ -40,9 +50,12 @@ test.describe('Device registration tests', () => {
await page.getByRole('textbox', { name: 'Given Name' }).fill('demouser');
await page.getByRole('textbox', { name: 'Family Name' }).fill('demouser');
await page.getByRole('button', { name: 'Continue' }).click();
await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible();
await expect(
async () =>
await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible(),
).toPass();
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByRole('button', { name: 'Logout' }).click();
expect(async () => await page.getByRole('button', { name: 'Logout' }).click()).toPass();

/***
* Login with the new user
Expand All @@ -52,7 +65,7 @@ test.describe('Device registration tests', () => {
await expect(page.getByText('SDK Automation - Sign On')).toBeVisible();
await page.getByRole('textbox', { name: 'Username' }).fill(username);
await page.getByRole('textbox', { name: 'Password' }).fill(password);
await page.getByRole('button', { name: 'Sign On' }).click();
expect(async () => await page.getByRole('button', { name: 'Sign On' }).click()).toPass();

/** Register a device */
await expect(page.getByText('Select Test Form')).toBeVisible();
Expand Down Expand Up @@ -83,10 +96,10 @@ test.describe('Device registration tests', () => {
await page.getByRole('textbox', { name: 'Password' }).fill(password);
await page.getByRole('textbox', { name: 'Given Name' }).fill('demouser');
await page.getByRole('textbox', { name: 'Family Name' }).fill('demouser');
await page.getByRole('button', { name: 'Continue' }).click();
expect(async () => await page.getByRole('button', { name: 'Continue' }).click()).toPass();
await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible();
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByRole('button', { name: 'Logout' }).click();
expect(async () => await page.getByRole('button', { name: 'Logout' }).click()).toPass();

/**
* Login with the new user
Expand All @@ -96,7 +109,7 @@ test.describe('Device registration tests', () => {
await expect(page.getByText('SDK Automation - Sign On')).toBeVisible();
await page.getByRole('textbox', { name: 'Username' }).fill(username);
await page.getByRole('textbox', { name: 'Password' }).fill(password);
await page.getByRole('button', { name: 'Sign On' }).click();
expect(async () => await page.getByRole('button', { name: 'Sign On' }).click()).toPass();

/** Register a Device */
await expect(page.getByText('Select Test Form')).toBeVisible();
Expand All @@ -107,6 +120,6 @@ test.describe('Device registration tests', () => {
await page.getByRole('textbox', { name: 'Enter Phone Number' }).fill('3035550100');
await page.getByRole('button', { name: 'Submit' }).click();
await expect(page.getByText('SMS/Voice MFA Registered')).toBeVisible();
await page.getByRole('button', { name: 'Continue' }).click();
expect(async () => await page.getByRole('button', { name: 'Continue' }).click()).toPass();
});
});
4 changes: 4 additions & 0 deletions e2e/oidc-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@
*/

import './styles.css';

// window.addEventListener('load', () => {
// console.log('loaded parent');
// });
8 changes: 6 additions & 2 deletions e2e/oidc-app/src/ping-am/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
#logout {
display: none;
}
#app {
display: none;
}
</style>
</head>
<body>
<a href="/">Home</a>
<h1>OIDC App | PingAM Login</h1>
<p id="loading">Loading...</p>
<div id="app">
<a href="/">Home</a>
<h1>OIDC App | PingAM Login</h1>
<button id="login-background">Login (Background)</button>
<button id="login-redirect">Login (Redirect)</button>
<button id="get-tokens">Get Tokens</button>
Expand Down
8 changes: 6 additions & 2 deletions e2e/oidc-app/src/ping-am/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@ const config = {
'https://openam-sdks.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
},
};

oidcApp({ config, urlParams });
document.addEventListener('DOMContentLoaded', async () => {
console.log('loaded outside');
// (async () => {
await oidcApp({ config, urlParams });
// })();
});
8 changes: 6 additions & 2 deletions e2e/oidc-app/src/ping-one/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
#logout {
display: none;
}
#app {
display: none;
}
</style>
</head>
<body>
<a href="/">Home</a>
<h1>OIDC App | PingOne Login</h1>
<p id="loading">Loading...</p>
<div id="app">
<a href="/">Home</a>
<h1>OIDC App | P1 Login</h1>
<button id="login-background">Login (Background)</button>
<button id="login-redirect">Login (Redirect)</button>
<button id="get-tokens">Get Tokens</button>
Expand Down
74 changes: 44 additions & 30 deletions e2e/oidc-app/src/utils/oidc-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
let tokenIndex = 0;

function displayError(error) {
// const appEl = document.getElementById('app');
const errorEl = document.createElement('div');
errorEl.innerHTML = `<p><strong>Error:</strong> <span class="error">${JSON.stringify(error, null, 2)}</span></p>`;
document.body.appendChild(errorEl);
Expand Down Expand Up @@ -52,39 +53,51 @@ export async function oidcApp({ config, urlParams }) {
const oidcClient = await oidc({ config });
if ('error' in oidcClient) {
displayError(oidcClient);
} else if (oidcClient) {
document.getElementById('app').style.display = 'block';
document.getElementById('loading').style.display = 'none';
}

document.getElementById('login-background').addEventListener('click', async () => {
const authorizeOptions: GetAuthorizationUrlOptions =
piflow === 'true'
? {
clientId: config.clientId,
redirectUri: config.redirectUri,
scope: config.scope,
responseType: config.responseType ?? 'code',
responseMode: 'pi.flow',
}
: undefined;
const response = await oidcClient.authorize.background(authorizeOptions);

if ('error' in response) {
console.error('Authorization Error:', response);
displayError(response);

if (response.redirectUrl) {
window.location.assign(response.redirectUrl);
} else {
console.log('Authorization failed with no ability to redirect:', response);
console.log('oidc app called');
// window.addEventListener('load', () => {
// console.log('loaded');
const myButton = document.getElementById('login-background');
if (myButton) {
console.log('button found');
myButton.addEventListener('click', async () => {
const authorizeOptions: GetAuthorizationUrlOptions =
piflow === 'true'
? {
clientId: config.clientId,
redirectUri: config.redirectUri,
scope: config.scope,
responseType: config.responseType ?? 'code',
responseMode: 'pi.flow',
}
: undefined;
const response = await oidcClient.authorize.background(authorizeOptions);

if ('error' in response) {
console.error('Authorization Error:', response);
displayError(response);

if (response.redirectUrl) {
window.location.assign(response.redirectUrl);
} else {
console.log('Authorization failed with no ability to redirect:', response);
}
return;

// Handle success response from background authorization
} else if ('code' in response) {
console.log('Authorization Code:', response.code);
const tokenResponse = await oidcClient.token.exchange(response.code, response.state);
displayTokenResponse(tokenResponse);
}
return;

// Handle success response from background authorization
} else if ('code' in response) {
console.log('Authorization Code:', response.code);
const tokenResponse = await oidcClient.token.exchange(response.code, response.state);
displayTokenResponse(tokenResponse);
}
});
});
} else {
console.log('not found');
}

document.getElementById('login-redirect').addEventListener('click', async () => {
const authorizeUrl = await oidcClient.authorize.url();
Expand Down Expand Up @@ -153,6 +166,7 @@ export async function oidcApp({ config, urlParams }) {
window.location.assign(window.location.origin + window.location.pathname);
}
});
// });

if (code && state) {
const response = await oidcClient.token.exchange(code, state);
Expand Down
10 changes: 10 additions & 0 deletions e2e/oidc-suites/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import baseConfig from '../../eslint.config.mjs';
import playwright from 'eslint-plugin-playwright';

export default [
...baseConfig,
Expand All @@ -19,4 +20,13 @@ export default [
// Override or add rules here
rules: {},
},
{
...playwright.configs['flat/recommended'],
files: ['src/*.spec.ts', 'src/utils/async-events.ts'],
rules: {
...playwright.configs['flat/recommended'].rules,
// Customize Playwright rules
// ...
},
},
];
48 changes: 29 additions & 19 deletions e2e/oidc-suites/src/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import { asyncEvents } from './utils/async-events.js';

test.describe('PingAM login and get token tests', () => {
test('background login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-am/');
const { /* navigate, */ clickButton } = asyncEvents(page);
// await page.goto('/ping-am/');
await page.goto('/ping-am/');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this change?

expect(page.url()).toBe('http://localhost:8443/ping-am/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Background)', '/authorize');

Expand All @@ -33,9 +35,10 @@ test.describe('PingAM login and get token tests', () => {
});

test('redirect login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-am/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-am/');
expect(page.url()).toBe('http://localhost:8443/ping-am/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Redirect)', '/authorize');

Expand All @@ -49,9 +52,10 @@ test.describe('PingAM login and get token tests', () => {
});

test('background login with invalid client id fails', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-am/?clientid=bad-id');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-am/?clientid=bad-id');
expect(page.url()).toBe('http://localhost:8443/ping-am/?clientid=bad-id');
await expect(page.locator('#loading')).toBeHidden();

await page.getByRole('button', { name: 'Login (Background)' }).click();

Expand All @@ -65,9 +69,10 @@ test.describe('PingAM login and get token tests', () => {

test.describe('PingOne login and get token tests', () => {
test('background login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Background)', '/authorize');

Expand All @@ -82,9 +87,10 @@ test.describe('PingOne login and get token tests', () => {
});

test('redirect login with valid credentials', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/');
expect(page.url()).toBe('http://localhost:8443/ping-one/');
await expect(page.locator('#loading')).toBeHidden();

await clickButton('Login (Redirect)', '/authorize');

Expand All @@ -99,9 +105,10 @@ test.describe('PingOne login and get token tests', () => {
});

test('login with invalid client id fails', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-one/?clientid=bad-id');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-one/?clientid=bad-id');
expect(page.url()).toBe('http://localhost:8443/ping-one/?clientid=bad-id');
await expect(page.locator('#loading')).toBeHidden();

await page.getByRole('button', { name: 'Login (Background)' }).click();

Expand All @@ -113,11 +120,12 @@ test.describe('PingOne login and get token tests', () => {
});

test('login with pi.flow response mode', async ({ page }) => {
const { navigate, clickButton } = asyncEvents(page);
await navigate('/ping-one/?piflow=true');
const { clickButton } = asyncEvents(page);
await page.goto('/ping-one/?piflow=true');
expect(page.url()).toBe('http://localhost:8443/ping-one/?piflow=true');
await expect(page.locator('#loading')).toBeHidden();

await page.on('request', (request) => {
page.on('request', (request) => {
const method = request.method();
const requestUrl = request.url();

Expand All @@ -140,9 +148,10 @@ test.describe('PingOne login and get token tests', () => {
});

test('login with invalid state fails with error', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-am/?code=12345&state=abcxyz');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-am/?code=12345&state=abcxyz');
expect(page.url()).toBe('http://localhost:8443/ping-am/?code=12345&state=abcxyz');
await expect(page.locator('#loading')).toBeHidden();

await expect(page.locator('.error')).toContainText(`"error": "State mismatch"`);
await expect(page.locator('.error')).toContainText(`"type": "state_error"`);
Expand All @@ -152,9 +161,10 @@ test('login with invalid state fails with error', async ({ page }) => {
});

test('oidc client fails to initialize with bad wellknown', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/ping-am/?wellknown=bad-wellknown');
// const { navigate } = asyncEvents(page);
await page.goto('/ping-am/?wellknown=bad-wellknown');
expect(page.url()).toBe('http://localhost:8443/ping-am/?wellknown=bad-wellknown');
await expect(page.locator('#loading')).toBeHidden();

await page.getByRole('button', { name: 'Login (Background)' }).click();

Expand Down
12 changes: 8 additions & 4 deletions e2e/oidc-suites/src/logout.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ test.describe('Logout tests', () => {

await page.getByLabel('User Name').fill(pingAmUsername);
await page.getByRole('textbox', { name: 'Password' }).fill(pingAmPassword);
await Promise.all([
page.waitForURL('http://localhost:8443/ping-am/**'),
page.getByRole('button', { name: 'Next' }).click(),
]);
const promise = page.waitForURL('http://localhost:8443/ping-am/**');
await page.getByRole('button', { name: 'Next' }).click();

/**
* This block is flakey, changing to this pattern
* https://playwright.dev/docs/network#network-events
**/
await promise;
expect(page.url()).toContain('code');
expect(page.url()).toContain('state');
await expect(page.getByRole('button', { name: 'Login (Background)' })).toBeHidden();
Expand Down
Loading
Loading