Skip to content

Commit 106867a

Browse files
committed
test(oidc): playwright updates v1
1 parent 7eff7b1 commit 106867a

11 files changed

Lines changed: 133 additions & 71 deletions

File tree

e2e/oidc-app/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@
88
*/
99

1010
import './styles.css';
11+
12+
// window.addEventListener('load', () => {
13+
// console.log('loaded parent');
14+
// });

e2e/oidc-app/src/ping-am/index.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
#logout {
88
display: none;
99
}
10+
#app {
11+
display: none;
12+
}
1013
</style>
1114
</head>
1215
<body>
16+
<a href="/">Home</a>
17+
<h1>OIDC App | PingAM Login</h1>
18+
<p id="loading">Loading...</p>
1319
<div id="app">
14-
<a href="/">Home</a>
15-
<h1>OIDC App | PingAM Login</h1>
1620
<button id="login-background">Login (Background)</button>
1721
<button id="login-redirect">Login (Redirect)</button>
1822
<button id="get-tokens">Get Tokens</button>

e2e/oidc-app/src/ping-am/main.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@ const config = {
2222
'https://openam-sdks.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
2323
},
2424
};
25-
26-
oidcApp({ config, urlParams });
25+
document.addEventListener('DOMContentLoaded', async () => {
26+
console.log('loaded outside');
27+
// (async () => {
28+
await oidcApp({ config, urlParams });
29+
// })();
30+
});

e2e/oidc-app/src/ping-one/index.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
#logout {
88
display: none;
99
}
10+
#app {
11+
display: none;
12+
}
1013
</style>
1114
</head>
1215
<body>
16+
<a href="/">Home</a>
17+
<h1>OIDC App | PingOne Login</h1>
18+
<p id="loading">Loading...</p>
1319
<div id="app">
14-
<a href="/">Home</a>
15-
<h1>OIDC App | P1 Login</h1>
1620
<button id="login-background">Login (Background)</button>
1721
<button id="login-redirect">Login (Redirect)</button>
1822
<button id="get-tokens">Get Tokens</button>

e2e/oidc-app/src/utils/oidc-app.ts

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type {
1818
let tokenIndex = 0;
1919

2020
function displayError(error) {
21+
// const appEl = document.getElementById('app');
2122
const errorEl = document.createElement('div');
2223
errorEl.innerHTML = `<p><strong>Error:</strong> <span class="error">${JSON.stringify(error, null, 2)}</span></p>`;
2324
document.body.appendChild(errorEl);
@@ -52,39 +53,51 @@ export async function oidcApp({ config, urlParams }) {
5253
const oidcClient = await oidc({ config });
5354
if ('error' in oidcClient) {
5455
displayError(oidcClient);
56+
} else if (oidcClient) {
57+
document.getElementById('app').style.display = 'block';
58+
document.getElementById('loading').style.display = 'none';
5559
}
5660

57-
document.getElementById('login-background').addEventListener('click', async () => {
58-
const authorizeOptions: GetAuthorizationUrlOptions =
59-
piflow === 'true'
60-
? {
61-
clientId: config.clientId,
62-
redirectUri: config.redirectUri,
63-
scope: config.scope,
64-
responseType: config.responseType ?? 'code',
65-
responseMode: 'pi.flow',
66-
}
67-
: undefined;
68-
const response = await oidcClient.authorize.background(authorizeOptions);
69-
70-
if ('error' in response) {
71-
console.error('Authorization Error:', response);
72-
displayError(response);
73-
74-
if (response.redirectUrl) {
75-
window.location.assign(response.redirectUrl);
76-
} else {
77-
console.log('Authorization failed with no ability to redirect:', response);
61+
console.log('oidc app called');
62+
// window.addEventListener('load', () => {
63+
// console.log('loaded');
64+
const myButton = document.getElementById('login-background');
65+
if (myButton) {
66+
console.log('button found');
67+
myButton.addEventListener('click', async () => {
68+
const authorizeOptions: GetAuthorizationUrlOptions =
69+
piflow === 'true'
70+
? {
71+
clientId: config.clientId,
72+
redirectUri: config.redirectUri,
73+
scope: config.scope,
74+
responseType: config.responseType ?? 'code',
75+
responseMode: 'pi.flow',
76+
}
77+
: undefined;
78+
const response = await oidcClient.authorize.background(authorizeOptions);
79+
80+
if ('error' in response) {
81+
console.error('Authorization Error:', response);
82+
displayError(response);
83+
84+
if (response.redirectUrl) {
85+
window.location.assign(response.redirectUrl);
86+
} else {
87+
console.log('Authorization failed with no ability to redirect:', response);
88+
}
89+
return;
90+
91+
// Handle success response from background authorization
92+
} else if ('code' in response) {
93+
console.log('Authorization Code:', response.code);
94+
const tokenResponse = await oidcClient.token.exchange(response.code, response.state);
95+
displayTokenResponse(tokenResponse);
7896
}
79-
return;
80-
81-
// Handle success response from background authorization
82-
} else if ('code' in response) {
83-
console.log('Authorization Code:', response.code);
84-
const tokenResponse = await oidcClient.token.exchange(response.code, response.state);
85-
displayTokenResponse(tokenResponse);
86-
}
87-
});
97+
});
98+
} else {
99+
console.log('not found');
100+
}
88101

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

157171
if (code && state) {
158172
const response = await oidcClient.token.exchange(code, state);

e2e/oidc-suites/eslint.config.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import baseConfig from '../../eslint.config.mjs';
2+
import playwright from 'eslint-plugin-playwright';
23

34
export default [
45
...baseConfig,
@@ -19,4 +20,13 @@ export default [
1920
// Override or add rules here
2021
rules: {},
2122
},
23+
{
24+
...playwright.configs['flat/recommended'],
25+
files: ['src/*.spec.ts', 'src/utils/async-events.ts'],
26+
rules: {
27+
...playwright.configs['flat/recommended'].rules,
28+
// Customize Playwright rules
29+
// ...
30+
},
31+
},
2232
];

e2e/oidc-suites/src/login.spec.ts

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ import { asyncEvents } from './utils/async-events.js';
1717

1818
test.describe('PingAM login and get token tests', () => {
1919
test('background login with valid credentials', async ({ page }) => {
20-
const { navigate, clickButton } = asyncEvents(page);
21-
await navigate('/ping-am/');
20+
const { /* navigate, */ clickButton } = asyncEvents(page);
21+
// await page.goto('/ping-am/');
22+
await page.goto('/ping-am/');
2223
expect(page.url()).toBe('http://localhost:8443/ping-am/');
24+
await expect(page.locator('#loading')).toBeHidden();
2325

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

120-
await page.on('request', (request) => {
128+
page.on('request', (request) => {
121129
const method = request.method();
122130
const requestUrl = request.url();
123131

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

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

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

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

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

e2e/oidc-suites/src/token.spec.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,20 @@ test.describe('PingAM tokens', () => {
105105

106106
test.describe('PingOne tokens', () => {
107107
test('login and get tokens', async ({ page }) => {
108-
const { navigate, clickButton } = asyncEvents(page);
109-
await navigate('/ping-one/');
108+
const { clickButton } = asyncEvents(page);
109+
await page.goto('/ping-one/');
110110
expect(page.url()).toBe('http://localhost:8443/ping-one/');
111+
await expect(page.locator('#loading')).toBeHidden();
111112

112113
await clickButton('Login (Background)', 'https://apps.pingone.ca/');
113114

114115
await page.getByLabel('Username').fill(pingOneUsername);
115116
await page.getByRole('textbox', { name: 'Password' }).fill(pingOnePassword);
117+
const promise = page.waitForURL('http://localhost:8443/ping-one/**');
116118
await page.getByRole('button', { name: 'Sign On' }).click();
117119

118-
await page.waitForURL('http://localhost:8443/ping-one/**', { waitUntil: 'networkidle' });
120+
await promise;
121+
await expect(page.locator('#loading')).toBeHidden();
119122
expect(page.url()).toContain('code');
120123
expect(page.url()).toContain('state');
121124

@@ -128,17 +131,20 @@ test.describe('PingOne tokens', () => {
128131
});
129132

130133
test('login and renew tokens', async ({ page }) => {
131-
const { navigate, clickButton } = asyncEvents(page);
132-
await navigate('/ping-one/');
134+
const { clickButton } = asyncEvents(page);
135+
await page.goto('/ping-one/');
133136
expect(page.url()).toBe('http://localhost:8443/ping-one/');
137+
await expect(page.locator('#loading')).toBeHidden();
134138

135139
await clickButton('Login (Background)', 'https://apps.pingone.ca/');
136140

137141
await page.getByLabel('Username').fill(pingOneUsername);
138142
await page.getByRole('textbox', { name: 'Password' }).fill(pingOnePassword);
143+
const promise = page.waitForURL('http://localhost:8443/ping-one/**');
139144
await page.getByRole('button', { name: 'Sign On' }).click();
140145

141-
await page.waitForURL('http://localhost:8443/ping-one/**', { waitUntil: 'networkidle' });
146+
await promise;
147+
await expect(page.locator('#loading')).toBeHidden();
142148
expect(page.url()).toContain('code');
143149
expect(page.url()).toContain('state');
144150

@@ -153,17 +159,20 @@ test.describe('PingOne tokens', () => {
153159
});
154160

155161
test('login and revoke tokens', async ({ page }) => {
156-
const { navigate, clickButton } = asyncEvents(page);
157-
await navigate('/ping-one/');
162+
const { clickButton } = asyncEvents(page);
163+
await page.goto('/ping-one/');
158164
expect(page.url()).toBe('http://localhost:8443/ping-one/');
165+
await expect(page.locator('#loading')).toBeHidden();
159166

160167
await clickButton('Login (Background)', 'https://apps.pingone.ca/');
161168

162169
await page.getByLabel('Username').fill(pingOneUsername);
163170
await page.getByRole('textbox', { name: 'Password' }).fill(pingOnePassword);
171+
const promise = page.waitForURL('http://localhost:8443/ping-one/**');
164172
await page.getByRole('button', { name: 'Sign On' }).click();
165173

166-
await page.waitForURL('http://localhost:8443/ping-one/**', { waitUntil: 'networkidle' });
174+
await promise;
175+
await expect(page.locator('#loading')).toBeHidden();
167176
expect(page.url()).toContain('code');
168177
expect(page.url()).toContain('state');
169178

@@ -176,9 +185,10 @@ test.describe('PingOne tokens', () => {
176185
});
177186

178187
test('renew tokens without logging in should error', async ({ page }) => {
179-
const { navigate } = asyncEvents(page);
180-
await navigate('/ping-one/');
188+
// const { clickButton } = asyncEvents(page);
189+
await page.goto('/ping-one/');
181190
expect(page.url()).toBe('http://localhost:8443/ping-one/');
191+
await expect(page.locator('#loading')).toBeHidden();
182192

183193
await page.getByRole('button', { name: 'Renew Tokens' }).click();
184194

0 commit comments

Comments
 (0)