Skip to content

Commit 6e2bce8

Browse files
authored
Merge pull request #312 from ForgeRock/fix-e2e-tests
fix: device-options-field
2 parents 192e98b + 5d71457 commit 6e2bce8

10 files changed

Lines changed: 128 additions & 43 deletions

File tree

.changeset/angry-roses-wash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@forgerock/davinci-client': patch
3+
---
4+
5+
Fixes the device-fields which were changed to options on the object

e2e/davinci-app/components/flow-link.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export default function flowLinkComponent(
1616

1717
button.classList.add('flow-link');
1818
button.type = 'button';
19+
button.name = collector.output.label || 'no-label-provided-err';
1920
button.innerText = collector.output.label;
2021

2122
formEl?.appendChild(button);

e2e/davinci-app/components/single-value.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export default function singleValueComponent(
2222
labelEl.textContent = collector.output.label || 'Select an option';
2323
labelEl.setAttribute('for', collector.output.key || 'dropdown-field');
2424
labelEl.className = 'dropdown-label';
25+
labelEl.setAttribute('for', collector.output.key || 'dropdown-field');
2526

2627
// Create the select element
2728
const selectEl = document.createElement('select');

e2e/davinci-suites/src/phone-number-field.test.ts

Lines changed: 102 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,114 @@
55
* of the MIT license. See the LICENSE file for details.
66
*/
77
import { expect, test } from '@playwright/test';
8-
import { asyncEvents } from './utils/async-events.js';
8+
import { password } from './utils/demo-user.js';
99

10-
test('Test happy paths on test page', async ({ page }) => {
11-
const { navigate } = asyncEvents(page);
12-
await navigate('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
10+
test('Login - add email device - authenticate with email device', async ({ page }) => {
11+
/** Go to page */
12+
await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
1313

14-
expect(page.url()).toBe('http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
15-
16-
await expect(page.getByText('Create Your Profile')).toBeVisible();
14+
expect(page.url()).toContain(
15+
'http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e',
16+
);
17+
/**
18+
* Register a new user
19+
*/
20+
await page.goto('http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
21+
await expect(page.getByRole('button', { name: 'USER_REGISTRATION' })).toBeVisible();
22+
await page.getByRole('button', { name: 'USER_REGISTRATION' }).click();
23+
await page.getByRole('textbox', { name: 'Email' }).click();
24+
await page.getByRole('textbox', { name: 'Email' }).fill('fakeemail@user.com');
25+
await page.getByRole('textbox', { name: 'Password' }).fill('U.QPDWEN47ZMyJhCDmhGLK*nr');
26+
await page.getByRole('textbox', { name: 'Given Name' }).fill('demouser');
27+
await page.getByRole('textbox', { name: 'Family Name' }).fill('demouser');
28+
expect(await page.getByRole('button', { name: 'Continue' })).toBeVisible();
29+
await page.getByRole('button', { name: 'Continue' }).click();
30+
await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible();
31+
await page.getByRole('button').click();
32+
await page.getByRole('button', { name: 'Logout' }).click();
33+
/***
34+
* Login with the new user
35+
**/
36+
await page.goto('http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
37+
await page.getByRole('button', { name: 'USER_LOGIN' }).click();
38+
await page.getByText('SDK Automation - Sign On');
39+
await page.getByRole('textbox', { name: 'Username' }).fill('fakeemail@user.com');
40+
await page.getByRole('textbox', { name: 'Password' }).fill(password);
41+
await page.getByRole('button', { name: 'Sign On' }).click();
1742

18-
await page.getByLabel('Email Address').fill('test@test.com');
19-
await page.getByLabel('Password').fill('apassword');
20-
await page.getByLabel('Placeholder').fill('12345678901');
43+
/** Register a device */
44+
await page.getByText('Select Test Form');
45+
await page.getByRole('button', { name: 'DEVICE_REGISTRATION' }).click();
46+
await page.getByText('SDK Automation - Device Registration');
47+
await page.getByRole('button', { name: 'Email' }).click();
48+
await page.getByText('SDK Automation - Device Registration');
49+
await page.getByRole('textbox', { name: 'Email Address' }).fill('test+my_fake_user@example.com');
50+
await page.getByRole('button', { name: 'Submit' }).click();
51+
await expect(page.getByText('EMAIL MFA Registered')).toBeVisible();
52+
await page.getByRole('button').click();
2153

22-
const requestPromise = page.waitForRequest((request) =>
23-
request
24-
.url()
25-
.includes(
26-
'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/davinci/connections/8209285e0d2f3fc76bfd23fd10d45e6f/capabilities/customForm?next=true',
27-
),
54+
/** Authenticate with the Device */
55+
await page.getByRole('button', { name: 'DEVICE_AUTHENTICATION' }).click();
56+
await page.getByText('SDK Automation - Device Authentication');
57+
await page.getByRole('button', { name: 'Email' }).click();
58+
await page.getByRole('button', { name: 'USER_DELETE' }).click();
59+
await page.getByRole('heading', { name: 'Success' });
60+
await page.getByRole('button', { name: 'Start over' }).click();
61+
});
62+
test('Login - add phone device - authenticate with phone device', async ({ page }) => {
63+
await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
64+
/***
65+
* Go to page
66+
***/
67+
expect(page.url()).toContain(
68+
'http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e',
2869
);
2970

71+
/**
72+
* Register a new user
73+
**/
74+
await page.goto('http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
75+
await expect(page.getByRole('button', { name: 'USER_REGISTRATION' })).toBeVisible();
76+
await page.getByRole('button', { name: 'USER_REGISTRATION' }).click();
77+
await page.getByRole('textbox', { name: 'Email' }).click();
78+
await page.getByRole('textbox', { name: 'Email' }).fill('fakeemail2@user.com');
79+
await page.getByRole('textbox', { name: 'Password' }).fill('U.QPDWEN47ZMyJhCDmhGLK*nr');
80+
await page.getByRole('textbox', { name: 'Given Name' }).fill('demouser');
81+
await page.getByRole('textbox', { name: 'Family Name' }).fill('demouser');
82+
expect(await page.getByRole('button', { name: 'Continue' })).toBeVisible();
83+
await page.getByRole('button', { name: 'Continue' }).click();
84+
await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible();
85+
await page.getByRole('button').click();
86+
await page.getByRole('button', { name: 'Logout' }).click();
87+
await page.goto('http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
88+
89+
/**
90+
* Login with the new user
91+
**/
92+
await page.getByRole('button', { name: 'USER_LOGIN' }).click();
93+
await page.getByText('SDK Automation - Sign On');
94+
await page.getByRole('textbox', { name: 'Username' }).fill('fakeemail2@user.com');
95+
await page.getByRole('textbox', { name: 'Password' }).fill(password);
96+
await page.getByRole('button', { name: 'Sign On' }).click();
97+
98+
/** Register a Device */
99+
await page.getByText('Select Test Form');
100+
await page.getByRole('button', { name: 'DEVICE_REGISTRATION' }).click();
101+
await page.getByText('SDK Automation - Device Registration');
102+
await page.getByRole('button', { name: 'Text Message' }).click();
103+
await expect(page.getByText('SDK Automation - Enter Phone Number')).toBeVisible();
104+
await expect(page.locator('#countryCode')).toBeVisible();
105+
await page.locator('#countryCode').selectOption('1');
106+
await page.getByRole('textbox', { name: 'Enter Phone Number' }).fill('3035550100');
30107
await page.getByRole('button', { name: 'Submit' }).click();
108+
await expect(page.getByText('SMS/Voice MFA Registered')).toBeVisible();
109+
await page.getByRole('button').click();
31110

32-
const request = await requestPromise;
33-
const postedData = JSON.parse(request.postData());
34-
const data = postedData.parameters.data;
35-
expect(data).toEqual({
36-
actionKey: 'submit',
37-
formData: {
38-
'user.email': 'test@test.com',
39-
'user.password': 'apassword',
40-
'phone-field': { phoneNumber: '12345678901', countryCode: 'CA' },
41-
},
42-
});
111+
/** Authenticate with the Device */
112+
await page.getByRole('button', { name: 'DEVICE_AUTHENTICATION' }).click();
113+
await page.getByText('SDK Automation - Device Authentication');
114+
await page.getByRole('button', { name: 'Text Message' }).click();
115+
await page.getByRole('button', { name: 'USER_DELETE' }).click();
116+
await page.getByRole('heading', { name: 'Success' });
117+
await page.getByRole('button', { name: 'Start over' }).click();
43118
});

e2e/davinci-suites/src/register.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { expect, test } from '@playwright/test';
88
import { asyncEvents } from './utils/async-events.js';
99
import { password } from './utils/demo-user.js';
1010

11-
test('Test happy paths on test page', async ({ page }) => {
11+
test.skip('Test happy paths on test page', async ({ page }) => {
1212
const { navigate } = asyncEvents(page);
1313
await navigate('/');
1414

e2e/davinci-suites/src/utils/demo-user.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@
66
*/
77
export const username = 'demouser';
88
export const password = 'U.QPDWEN47ZMyJhCDmhGLK*nr';
9+
export const phoneNumber1 = '888123456';
10+
export const phoneNumber2 = '888123457';

packages/davinci-client/src/lib/collector.utils.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ describe('Object value collectors', () => {
420420
key: 'device-auth-key',
421421
label: 'Device Authentication',
422422
type: 'DEVICE_AUTHENTICATION',
423-
devices: [
423+
options: [
424424
{
425425
type: 'device1',
426426
iconSrc: 'icon1.png',
@@ -441,7 +441,7 @@ describe('Object value collectors', () => {
441441
required: true,
442442
};
443443

444-
const transformedDevices = mockField.devices.map((device) => ({
444+
const transformedDevices = mockField.options.map((device) => ({
445445
label: device.title,
446446
value: device.id,
447447
content: device.value,
@@ -487,7 +487,7 @@ describe('Object value collectors', () => {
487487
key: 'device-reg-key',
488488
label: 'Device Registration',
489489
type: 'DEVICE_REGISTRATION',
490-
devices: [
490+
options: [
491491
{
492492
type: 'device1',
493493
iconSrc: 'icon1.png',
@@ -504,7 +504,7 @@ describe('Object value collectors', () => {
504504
required: true,
505505
};
506506

507-
const transformedDevices = mockField.devices.map((device, idx) => ({
507+
const transformedDevices = mockField.options.map((device, idx) => ({
508508
label: device.title,
509509
value: device.type,
510510
content: device.description,

packages/davinci-client/src/lib/collector.utils.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -360,26 +360,26 @@ export function returnObjectCollector<
360360
error = `${error}Type is not found in the field object. `;
361361
}
362362

363-
let devices;
363+
let options;
364364
let defaultValue;
365365

366366
if (field.type === 'DEVICE_AUTHENTICATION') {
367-
if (!('devices' in field)) {
367+
if (!('options' in field)) {
368368
error = `${error}Device options are not found in the field object. `;
369369
}
370-
if (Array.isArray(field.devices) && field.devices.length === 0) {
370+
if (Array.isArray(field.options) && field.options.length === 0) {
371371
error = `${error}Device options are not an array or is empty. `;
372372
}
373373

374-
const unmappedDefault = field.devices.find((device) => device.default);
374+
const unmappedDefault = field.options.find((device) => device.default);
375375
defaultValue = {
376376
type: unmappedDefault ? unmappedDefault.type : '',
377377
value: unmappedDefault ? unmappedDefault.value : '',
378378
id: unmappedDefault ? unmappedDefault.id : '',
379379
};
380380

381381
// Map DaVinci spec to normalized SDK API
382-
devices = field.devices.map((device) => ({
382+
options = field.options.map((device) => ({
383383
type: device.type,
384384
label: device.title,
385385
content: device.value,
@@ -388,18 +388,18 @@ export function returnObjectCollector<
388388
default: device.default,
389389
}));
390390
} else if (field.type === 'DEVICE_REGISTRATION') {
391-
if (!('devices' in field)) {
391+
if (!('options' in field)) {
392392
error = `${error}Device options are not found in the field object. `;
393393
}
394394

395-
if (Array.isArray(field.devices) && field.devices.length === 0) {
395+
if (Array.isArray(field.options) && field.options.length === 0) {
396396
error = `${error}Device options are not an array or is empty. `;
397397
}
398398

399399
defaultValue = '';
400400

401401
// Map DaVinci spec to normalized SDK API
402-
devices = field.devices.map((device, idx) => ({
402+
options = field.options.map((device, idx) => ({
403403
type: device.type,
404404
label: device.title,
405405
content: device.description,
@@ -428,7 +428,7 @@ export function returnObjectCollector<
428428
key: field.key,
429429
label: field.label,
430430
type: field.type,
431-
...(devices && { options: devices || [] }),
431+
...(options && { options: options || [] }),
432432
...(defaultValue && { value: defaultValue }),
433433
},
434434
} as InferValueObjectCollectorType<CollectorType>;

packages/davinci-client/src/lib/davinci.types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export type DeviceAuthenticationField = {
120120
type: 'DEVICE_AUTHENTICATION';
121121
key: string;
122122
label: string;
123-
devices: {
123+
options: {
124124
type: string;
125125
iconSrc: string;
126126
title: string;
@@ -135,7 +135,7 @@ export type DeviceRegistrationField = {
135135
type: 'DEVICE_REGISTRATION';
136136
key: string;
137137
label: string;
138-
devices: {
138+
options: {
139139
type: string;
140140
iconSrc: string;
141141
title: string;

packages/davinci-client/src/lib/node.reducer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ export const nodeCollectorReducer = createReducer(initialCollectorValues, (build
242242
if (typeof action.payload.id !== 'string') {
243243
throw new Error('Index argument must be a string');
244244
}
245+
245246
// Iterate through the options object and find option to update
246247
const option = collector.output.options.find(
247248
(option) => option.value === action.payload.value,

0 commit comments

Comments
 (0)