2023-04-20 11:21:21 -05:00
|
|
|
import crypto from 'node:crypto';
|
2023-05-22 00:31:45 -05:00
|
|
|
import path from 'node:path';
|
2023-04-20 11:21:21 -05:00
|
|
|
|
2023-01-12 07:50:23 -05:00
|
|
|
import { assert } from '@silverhand/essentials';
|
2023-09-12 05:42:15 -05:00
|
|
|
import { type Page } from 'puppeteer';
|
2023-01-12 07:50:23 -05:00
|
|
|
|
2022-12-13 21:13:17 -05:00
|
|
|
export const generateName = () => crypto.randomUUID();
|
2022-12-22 21:01:08 -05:00
|
|
|
export const generateUserId = () => crypto.randomUUID();
|
2022-06-30 14:18:44 -05:00
|
|
|
export const generateUsername = () => `usr_${crypto.randomUUID().replaceAll('-', '_')}`;
|
|
|
|
export const generatePassword = () => `pwd_${crypto.randomUUID()}`;
|
2022-07-20 22:37:51 -05:00
|
|
|
|
|
|
|
export const generateResourceName = () => `res_${crypto.randomUUID()}`;
|
|
|
|
export const generateResourceIndicator = () => `https://${crypto.randomUUID()}.logto.io`;
|
2022-11-09 03:25:54 -05:00
|
|
|
export const generateEmail = () => `${crypto.randomUUID().toLowerCase()}@logto.io`;
|
2023-01-11 03:13:35 -05:00
|
|
|
export const generateScopeName = () => `sc:${crypto.randomUUID()}`;
|
2023-01-11 03:36:31 -05:00
|
|
|
export const generateRoleName = () => `role_${crypto.randomUUID()}`;
|
2023-05-28 22:27:23 -05:00
|
|
|
export const generateDomain = () => `${crypto.randomUUID().toLowerCase().slice(0, 5)}.example.com`;
|
2022-07-31 20:51:27 -05:00
|
|
|
|
2023-05-22 00:31:45 -05:00
|
|
|
export const generatePhone = (isE164?: boolean) => {
|
|
|
|
const plus = isE164 ? '+' : '';
|
|
|
|
const countryAndAreaCode = '1310'; // California, US
|
|
|
|
const validCentralOfficeCodes = [
|
|
|
|
'205',
|
|
|
|
'208',
|
|
|
|
'215',
|
|
|
|
'216',
|
|
|
|
'220',
|
|
|
|
'228',
|
|
|
|
'229',
|
|
|
|
'230',
|
|
|
|
'231',
|
|
|
|
'232',
|
|
|
|
];
|
|
|
|
const centralOfficeCode =
|
|
|
|
validCentralOfficeCodes[Math.floor(Math.random() * validCentralOfficeCodes.length)] ?? '205';
|
|
|
|
const phoneNumber = Math.floor(Math.random() * 10_000)
|
|
|
|
.toString()
|
|
|
|
.padStart(4, '0');
|
2022-07-31 20:51:27 -05:00
|
|
|
|
2023-05-22 00:31:45 -05:00
|
|
|
return plus + countryAndAreaCode + centralOfficeCode + phoneNumber;
|
2022-07-31 20:51:27 -05:00
|
|
|
};
|
2022-12-26 06:59:33 -05:00
|
|
|
|
2023-05-22 00:31:45 -05:00
|
|
|
export const formatPhoneNumberToInternational = (phoneNumber: string) =>
|
|
|
|
phoneNumber.slice(0, 2) +
|
|
|
|
' ' +
|
|
|
|
phoneNumber.slice(2, 5) +
|
|
|
|
' ' +
|
|
|
|
phoneNumber.slice(5, 8) +
|
|
|
|
' ' +
|
|
|
|
phoneNumber.slice(8);
|
|
|
|
|
2022-12-26 06:59:33 -05:00
|
|
|
export const waitFor = async (ms: number) =>
|
|
|
|
new Promise((resolve) => {
|
|
|
|
setTimeout(resolve, ms);
|
|
|
|
});
|
2023-01-12 07:50:23 -05:00
|
|
|
|
|
|
|
export const getAccessTokenPayload = (accessToken: string): Record<string, unknown> => {
|
|
|
|
const payloadPart = accessToken.split('.')[1];
|
|
|
|
assert(typeof payloadPart === 'string', new Error('Invalid access token'));
|
|
|
|
const payload = Buffer.from(payloadPart, 'base64').toString();
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
|
|
return JSON.parse(payload) as Record<string, unknown>;
|
|
|
|
};
|
2023-05-22 00:31:45 -05:00
|
|
|
|
|
|
|
export const appendPathname = (pathname: string, baseUrl: URL) =>
|
|
|
|
new URL(path.join(baseUrl.pathname, pathname), baseUrl);
|
2023-07-27 03:04:28 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Run an action and simultaneously wait for navigation to complete. This is
|
|
|
|
* useful for actions that trigger navigation, such as clicking a link or
|
|
|
|
* submitting a form.
|
|
|
|
*/
|
2023-09-12 05:42:15 -05:00
|
|
|
export const expectNavigation = async <T>(
|
|
|
|
action: Promise<T>,
|
|
|
|
page: Page = global.page
|
|
|
|
): Promise<T> => {
|
2023-07-27 03:04:28 -05:00
|
|
|
const [result] = await Promise.all([
|
|
|
|
action,
|
|
|
|
page.waitForNavigation({ waitUntil: 'networkidle0' }),
|
|
|
|
]);
|
|
|
|
return result;
|
|
|
|
};
|