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
57 changes: 44 additions & 13 deletions e2e/davinci-app/components/object-value.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
Expand Down Expand Up @@ -75,33 +75,64 @@ export default function objectValueComponent(
phoneLabel.className = 'object-options-title';
phoneLabel.setAttribute('for', 'phone-number-input');

// Country code dropdown
const countryCodeLabel = document.createElement('label');
countryCodeLabel.textContent = 'Country Code';
countryCodeLabel.setAttribute('for', collector.output.key || 'dropdown-field');
countryCodeLabel.className = 'dropdown-label';
countryCodeLabel.setAttribute('for', collector.output.key || 'dropdown-field');

const countryCodeInput = document.createElement('select');
countryCodeInput.name = collector.output.key || 'dropdown-field';
countryCodeInput.id = collector.output.key || 'dropdown-field';

const countryCodes = ['IN', 'BR', 'CA', 'US'];
for (const option of countryCodes) {
const optionEl = document.createElement('option');
optionEl.value = option;
optionEl.textContent = option;
countryCodeInput.appendChild(optionEl);
}

// Phone number input
const phoneInput = document.createElement('input');
phoneInput.setAttribute('type', 'tel');
phoneInput.setAttribute('id', 'phone-number-input');
phoneInput.setAttribute('name', 'phone-number-input');
phoneInput.setAttribute('placeholder', 'Enter phone number');

formEl.appendChild(countryCodeLabel);
formEl.appendChild(countryCodeInput);
formEl.appendChild(phoneLabel);
formEl.appendChild(phoneInput);

// Add change event listener
const phoneNumberUpdater = updater as Updater<PhoneNumberCollector>;

// Add change event listener for phone number input
phoneInput.addEventListener('change', (event) => {
// Properly type the event target
const target = event.target as HTMLInputElement;
const selectedValue = target.value;

if (!selectedValue) {
console.error('No value found for the selected option');
return;
}

const phoneValue = target.value;
const countryCodeValue = countryCodeInput.value;
const phoneNumberInputValue: PhoneNumberInputValue = {
phoneNumber: selectedValue,
countryCode: collector.output.value?.countryCode || '',
phoneNumber: phoneValue,
countryCode: countryCodeValue || collector.output.value?.countryCode || '',
};
const phoneNumberUpdater = updater as Updater<PhoneNumberCollector>;

phoneNumberUpdater(phoneNumberInputValue);
});

// Add change event listener for extension input
countryCodeInput.addEventListener('change', (event) => {
const target = event.target as HTMLSelectElement;
const countryCodeValue = target.value;
const phoneValue = phoneInput.value;
const countryCodeInputValue: PhoneNumberInputValue = {
phoneNumber: phoneValue,
countryCode: countryCodeValue || collector.output.value?.countryCode || '',
};

phoneNumberUpdater(countryCodeInputValue);
});
} else if (collector.type === 'PhoneNumberExtensionCollector') {
const phoneLabel = document.createElement('label');
phoneLabel.textContent = collector.output.label || 'Phone Number';
Expand Down
2 changes: 1 addition & 1 deletion e2e/davinci-app/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const qs = window.location.search;
const searchParams = new URLSearchParams(qs);

const config: DaVinciConfig =
serverConfigs[searchParams.get('clientId') || '724ec718-c41c-4d51-98b0-84a583f450f9'];
serverConfigs[searchParams.get('clientId') || '625e45e0-dde5-402e-9bf9-7da1275df03a'];

const logger: { level: 'debug'; custom?: typeof loggerFn } = {
level: 'debug' as const,
Expand Down
42 changes: 10 additions & 32 deletions e2e/davinci-app/server-configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,20 @@ export const serverConfigs: Record<string, DaVinciConfig> = {
},
},
/**
* SDK Team Tenant
* DemoUser-sdkWebClient
* Login Registration
*/
'724ec718-c41c-4d51-98b0-84a583f450f9': {
clientId: '724ec718-c41c-4d51-98b0-84a583f450f9',
'625e45e0-dde5-402e-9bf9-7da1275df03a': {
clientId: '625e45e0-dde5-402e-9bf9-7da1275df03a',
redirectUri: window.location.origin + '/',
scope: 'openid profile email name revoke',
serverConfig: {
wellknown:
'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration',
},
},
/**
* Form Fields (old env — image feature flag enabled)
*/
'60de77d5-dd2c-41ef-8c40-f8bb2381a359': {
clientId: '60de77d5-dd2c-41ef-8c40-f8bb2381a359',
redirectUri: window.location.origin + '/',
scope: 'openid profile email name revoke',
serverConfig: {
wellknown:
'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration',
'https://auth.pingone.ca/356a254c-cba3-4ade-be1a-860136e8df01/as/.well-known/openid-configuration',
},
},
/**
* Form Fields
* QR Code
* ValidatedPasswordCollector / Password Policy
*/
'e4ef2896-8d90-4abd-bf0f-7b8034995927': {
Expand All @@ -72,29 +60,19 @@ export const serverConfigs: Record<string, DaVinciConfig> = {
},
},
/**
* Phone Number Input With Email and Password
* MFA: FIDO, Email, SMS
*/
'20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0': {
clientId: '20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0',
'9c1d9655-7d1b-46f3-a96d-345690259d2a': {
clientId: '9c1d9655-7d1b-46f3-a96d-345690259d2a',
redirectUri: window.location.origin + '/',
scope: 'openid profile email revoke',
serverConfig: {
wellknown:
'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration',
},
},
/** QR Code policy id : aa3c00c3ec25a9721be078f7bf44678d **/
'c12743f9-08e8-4420-a624-71bbb08e9fe1': {
clientId: 'c12743f9-08e8-4420-a624-71bbb08e9fe1',
redirectUri: window.location.origin + '/',
scope: 'openid profile email',
serverConfig: {
wellknown:
'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration',
'https://auth.pingone.ca/356a254c-cba3-4ade-be1a-860136e8df01/as/.well-known/openid-configuration',
},
},
/**
* AutoCollectors: Polling, Metadata, FIDO, Protect
* AutoCollectors: Polling, Metadata, Protect
*/
'31a587ce-9aa4-4f36-a09f-78cd8a0a74a0': {
clientId: '31a587ce-9aa4-4f36-a09f-78cd8a0a74a0',
Expand Down
7 changes: 4 additions & 3 deletions e2e/davinci-suites/src/basic.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
Expand Down Expand Up @@ -39,6 +39,7 @@ test('Test happy paths on test page', async ({ page }) => {
if (response.url().includes('/revoke') && response.status() === 200) {
return true;
}
return false;
});
await logoutButton.click();
await revokeCall;
Expand All @@ -50,7 +51,7 @@ test('ensure query params passed to start are sent off in authorize call', async
const requestPromise = page.waitForRequest((request) => {
return request
.url()
.includes('https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/authorize');
.includes('https://auth.pingone.ca/356a254c-cba3-4ade-be1a-860136e8df01/as/authorize');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Non-blocking: All of these IDs make me just a bit nervous. I feel we should centralize all of these IDs and then pass them around, rather than needing to hardcode them all throughout our files.

});
await navigate('/?testParam=123');

Expand All @@ -62,7 +63,7 @@ test('ensure query params passed to start are sent off in authorize call', async
const queryParams = Object.fromEntries(url.searchParams.entries());

expect(queryParams['testParam']).toBe('123');
expect(queryParams['client_id']).toBe('724ec718-c41c-4d51-98b0-84a583f450f9');
expect(queryParams['client_id']).toBe('625e45e0-dde5-402e-9bf9-7da1275df03a');
expect(queryParams['response_mode']).toBe('pi.flow');

expect(page.url()).toBe('http://localhost:5829/?testParam=123');
Expand Down
4 changes: 2 additions & 2 deletions e2e/davinci-suites/src/fido.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { asyncEvents } from './utils/async-events.js';
const username = 'JSFidoUser@user.com';
const password = 'FakePassword#123';

const clientId = '31a587ce-9aa4-4f36-a09f-78cd8a0a74a0';
const policyId = '3eff62cf953372519225d375fd200358';
const clientId = '9c1d9655-7d1b-46f3-a96d-345690259d2a';
const policyId = '4b6008f10ba174dd3ce3ab60c5b81d7e';

test.use({ browserName: 'chromium' }); // ensure CDP/WebAuthn is available
test.describe.configure({ mode: 'serial' });
Expand Down
4 changes: 2 additions & 2 deletions e2e/davinci-suites/src/form-image.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import { asyncEvents } from './utils/async-events.js';

test('Should render image collector in form', async ({ page }) => {
const { navigate } = asyncEvents(page);
await navigate('/?clientId=60de77d5-dd2c-41ef-8c40-f8bb2381a359');
await navigate('/?clientId=e4ef2896-8d90-4abd-bf0f-7b8034995927');

await expect(page.getByText('Select Test Form')).toBeVisible();
await expect(page.getByText('Select Form Fields Test Form')).toBeVisible();
await page.getByRole('button', { name: 'Form Fields' }).click();

await expect(page.getByText('Form Fields Tests')).toBeVisible();
Expand Down
20 changes: 10 additions & 10 deletions e2e/davinci-suites/src/middleware.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
Expand All @@ -9,7 +9,7 @@ import { asyncEvents } from './utils/async-events.js';
import { password, username } from './utils/demo-user.js';

test('Test middleware on test page', async ({ page }) => {
const networkArray = [];
const networkArray: { url: string; langHeader: string | null }[] = [];
page.on('request', async (req) => {
const url = req.url().toString();
const langHeader = await req.headerValue('Accept-Language');
Expand All @@ -36,14 +36,14 @@ test('Test middleware on test page', async ({ page }) => {
const nextRequest = networkArray.find((req) => req.url.includes('/customHTMLTemplate'));

// Check for addition of query params
await expect(startRequest.url.includes('start=true')).toBeTruthy();
await expect(startRequest.url.includes('next=true')).toBeFalsy();
await expect(nextRequest.url.includes('next=true')).toBeTruthy();
await expect(nextRequest.url.includes('start=true')).toBeFalsy();
await expect(startRequest?.url.includes('start=true')).toBeTruthy();
await expect(startRequest?.url.includes('next=true')).toBeFalsy();
await expect(nextRequest?.url.includes('next=true')).toBeTruthy();
await expect(nextRequest?.url.includes('start=true')).toBeFalsy();

// Check that Accept-Language header was modified from default en-US locale
await expect(startRequest.langHeader).not.toContain('en-US');
await expect(startRequest.langHeader).toBe('xx-XX');
await expect(nextRequest.langHeader).not.toContain('en-US');
await expect(nextRequest.langHeader).toBe('zz-ZZ');
await expect(startRequest?.langHeader).not.toContain('en-US');
await expect(startRequest?.langHeader).toBe('xx-XX');
await expect(nextRequest?.langHeader).not.toContain('en-US');
await expect(nextRequest?.langHeader).toBe('zz-ZZ');
});
2 changes: 1 addition & 1 deletion e2e/davinci-suites/src/password-policy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { asyncEvents } from './utils/async-events.js';
import { password } from './utils/demo-user.js';

const CLIENT_ID = 'e4ef2896-8d90-4abd-bf0f-7b8034995927';
const POLICY_ID = '5e8613e337c67a67db09373019e962e0';
const POLICY_ID = '93d0e640dcf435ffc458228bca04be5f';

/**
* A unique email per test run to avoid conflicts with existing accounts.
Expand Down
50 changes: 27 additions & 23 deletions e2e/davinci-suites/src/phone-number-field.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
Expand All @@ -9,9 +9,11 @@ import { password } from './utils/demo-user.js';

test.describe('Device registration tests', () => {
const username = 'fakeemail@user.com';
const clientId = '9c1d9655-7d1b-46f3-a96d-345690259d2a';
const policyId = '4b6008f10ba174dd3ce3ab60c5b81d7e';

test.afterEach(async ({ page }) => {
await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`);

await page.getByRole('button', { name: 'USER_LOGIN' }).click();
await page.getByRole('textbox', { name: 'Username' }).fill(username);
Expand All @@ -24,40 +26,41 @@ test.describe('Device registration tests', () => {

test('Login - add email device - authenticate with email device', async ({ page }) => {
/** Go to page */
await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`);

expect(page.url()).toContain(
'http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0',
`http://localhost:5829/?clientId=${clientId}&acr_values=${policyId}`,
);
await expect(page.getByText('Select Test Form')).toBeVisible();
await expect(page.getByText('FIDO2 Test Form')).toBeVisible();

/**
* Register a new user
*/
await page.getByRole('button', { name: 'USER_REGISTRATION' }).click();
await page.getByRole('textbox', { name: 'Email' }).fill(username);

await page.getByRole('textbox', { name: 'Username' }).fill(username);
await page.getByRole('textbox', { name: 'Email Address' }).fill(username);
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();
await page.getByRole('button', { name: 'Submit' }).click();

await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible();
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByRole('button', { name: 'Logout' }).click();

/***
* Login with the new user
**/
await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`);
await page.getByRole('button', { name: 'USER_LOGIN' }).click();
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();

/** Register a device */
await expect(page.getByText('Select Test Form')).toBeVisible();
await expect(page.getByText('FIDO2 Test Form')).toBeVisible();
await page.getByRole('button', { name: 'DEVICE_REGISTRATION' }).click();
await expect(page.getByText('SDK Automation - Device Registration')).toBeVisible();
await expect(page.getByText('MFA Device Selection - Registration')).toBeVisible();
await page.getByRole('button', { name: 'Email' }).click();
await page
.getByRole('textbox', { name: 'Email Address' })
Expand All @@ -69,41 +72,42 @@ test.describe('Device registration tests', () => {

test('Login - add phone device - authenticate with phone device', async ({ page }) => {
/** Go to page */
await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`);
expect(page.url()).toContain(
'http://localhost:5829/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0',
`http://localhost:5829/?clientId=${clientId}&acr_values=${policyId}`,
);

/**
* Register a new user
**/
await expect(page.getByText('Select Test Form')).toBeVisible();
await expect(page.getByText('FIDO2 Test Form')).toBeVisible();
await page.getByRole('button', { name: 'USER_REGISTRATION' }).click();
await page.getByRole('textbox', { name: 'Email' }).fill(username);
await page.getByRole('textbox', { name: 'Username' }).fill(username);
await page.getByRole('textbox', { name: 'Email Address' }).fill(username);
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();
await page.getByRole('button', { name: 'Submit' }).click();

await expect(page.getByRole('heading', { name: 'Registration Complete' })).toBeVisible();
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByRole('button', { name: 'Logout' }).click();

/**
* Login with the new user
**/
await page.goto('/?clientId=20dd0ed0-bb9b-4c8f-9a60-9ebeb4b348e0');
await page.goto(`/?clientId=${clientId}&acr_values=${policyId}`);
await page.getByRole('button', { name: 'USER_LOGIN' }).click();
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();

/** Register a Device */
await expect(page.getByText('Select Test Form')).toBeVisible();
await expect(page.getByText('FIDO2 Test Form')).toBeVisible();
await page.getByRole('button', { name: 'DEVICE_REGISTRATION' }).click();
await expect(page.getByText('SDK Automation - Device Registration')).toBeVisible();
await expect(page.getByText('MFA Device Selection - Registration')).toBeVisible();
await page.getByRole('button', { name: 'Text Message' }).click();
await expect(page.getByText('SDK Automation [JS] - Enter Phone Number')).toBeVisible();
await expect(page.getByText('SDK Automation - Standard Phone Number')).toBeVisible();
await page.getByLabel('Country Code').selectOption('US');
await page.getByRole('textbox', { name: 'Enter Phone Number' }).fill('3035550100');
await expect(page.getByText('Extension')).not.toBeVisible(); // Tests standard PhoneNumberCollector
await page.getByRole('button', { name: 'Submit' }).click();
Expand Down
Loading
Loading