forked from trent_larson/crowd-funder-for-time-pwa
refactor: extract test user data and improve "New offers" test flow
- Extract test user data (seed phrases, DIDs, usernames) from importUser into separate getTestUserData function
- Refactor importUser to use getTestUserData internally, maintaining backward compatibility
- Update "New offers for another user" test to use new getTestUserData function
- Replace hardcoded seed phrase with programmatic retrieval using getTestUserData('00')
- Add proper TypeScript type annotations to array functions in testUtils
- Improve test maintainability by centralizing test user data management
This allows tests to access user data without executing import flow, providing more flexibility for test scenarios.
This commit is contained in:
@@ -693,6 +693,7 @@ export class WebPlatformService implements PlatformService {
|
|||||||
const setClause = keys.map((key) => `${key} = ?`).join(", ");
|
const setClause = keys.map((key) => `${key} = ?`).join(", ");
|
||||||
const sql = `UPDATE settings SET ${setClause} WHERE accountDid = ?`;
|
const sql = `UPDATE settings SET ${setClause} WHERE accountDid = ?`;
|
||||||
const params = [...keys.map((key) => settings[key]), did];
|
const params = [...keys.map((key) => settings[key]), did];
|
||||||
|
console.log("[WebPlatformService] updateDidSpecificSettings", sql, JSON.stringify(params, null, 2));
|
||||||
await this.dbExec(sql, params);
|
await this.dbExec(sql, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -707,6 +707,7 @@ export const PlatformServiceMixin = {
|
|||||||
// Merge with any provided defaults (these take highest precedence)
|
// Merge with any provided defaults (these take highest precedence)
|
||||||
const finalSettings = { ...mergedSettings, ...defaults };
|
const finalSettings = { ...mergedSettings, ...defaults };
|
||||||
|
|
||||||
|
console.log("[PlatformServiceMixin] $accountSettings", JSON.stringify(finalSettings, null, 2));
|
||||||
return finalSettings;
|
return finalSettings;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|||||||
@@ -828,15 +828,19 @@ export default class ContactsView extends Vue {
|
|||||||
* Handle registration prompt for new contacts
|
* Handle registration prompt for new contacts
|
||||||
*/
|
*/
|
||||||
private async handleRegistrationPrompt(newContact: Contact): Promise<void> {
|
private async handleRegistrationPrompt(newContact: Contact): Promise<void> {
|
||||||
|
console.log("[ContactsView] handleRegistrationPrompt", this.isRegistered, this.hideRegisterPromptOnNewContact, newContact.registered);
|
||||||
if (
|
if (
|
||||||
!this.isRegistered ||
|
this.isRegistered === false || // the current Identity is not registered OR
|
||||||
this.hideRegisterPromptOnNewContact ||
|
this.hideRegisterPromptOnNewContact === true || // the user has hidden the registrationprompt OR
|
||||||
newContact.registered
|
newContact.registered === true // the new contact is already registered
|
||||||
) {
|
) {
|
||||||
|
// if any of the above are true, we do not want to show the registration prompt
|
||||||
|
console.log("[ContactsView] handleRegistrationPrompt we do not want to show the registration prompt");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
console.log("[ContactsView] handleRegistrationPrompt setTimeout");
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "modal",
|
group: "modal",
|
||||||
@@ -844,18 +848,22 @@ export default class ContactsView extends Vue {
|
|||||||
title: "Register",
|
title: "Register",
|
||||||
text: "Do you want to register them?",
|
text: "Do you want to register them?",
|
||||||
onCancel: async (stopAsking?: boolean) => {
|
onCancel: async (stopAsking?: boolean) => {
|
||||||
|
console.log("[ContactsView] handleRegistrationPrompt onCancel", stopAsking);
|
||||||
await this.handleRegistrationPromptResponse(stopAsking);
|
await this.handleRegistrationPromptResponse(stopAsking);
|
||||||
},
|
},
|
||||||
onNo: async (stopAsking?: boolean) => {
|
onNo: async (stopAsking?: boolean) => {
|
||||||
|
console.log("[ContactsView] handleRegistrationPrompt onNo", stopAsking);
|
||||||
await this.handleRegistrationPromptResponse(stopAsking);
|
await this.handleRegistrationPromptResponse(stopAsking);
|
||||||
},
|
},
|
||||||
onYes: async () => {
|
onYes: async () => {
|
||||||
|
console.log("[ContactsView] handleRegistrationPrompt onYes");
|
||||||
await this.register(newContact);
|
await this.register(newContact);
|
||||||
},
|
},
|
||||||
promptToStopAsking: true,
|
promptToStopAsking: true,
|
||||||
},
|
},
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
|
console.log("[ContactsView] handleRegistrationPrompt setTimeout done");
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Raymer * @version 1.0.0 */
|
|||||||
<TopMessage />
|
<TopMessage />
|
||||||
|
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
|
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto" :data-active-did="activeDid">
|
||||||
<h1 id="ViewHeading" class="text-4xl text-center font-light mb-8">
|
<h1 id="ViewHeading" class="text-4xl text-center font-light mb-8">
|
||||||
{{ AppString.APP_NAME }}
|
{{ AppString.APP_NAME }}
|
||||||
<span class="text-xs text-gray-500">{{ package.version }}</span>
|
<span class="text-xs text-gray-500">{{ package.version }}</span>
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ export default class ImportAccountView extends Vue {
|
|||||||
* Uses importFromMnemonic utility for secure import
|
* Uses importFromMnemonic utility for secure import
|
||||||
*/
|
*/
|
||||||
public async onImportClick() {
|
public async onImportClick() {
|
||||||
|
console.log("[ImportAccountView] onImportClick", this.mnemonic);
|
||||||
if (!this.mnemonic?.trim()) {
|
if (!this.mnemonic?.trim()) {
|
||||||
this.notify.warning(
|
this.notify.warning(
|
||||||
"Seed phrase is required to import an account.",
|
"Seed phrase is required to import an account.",
|
||||||
@@ -206,6 +207,7 @@ export default class ImportAccountView extends Vue {
|
|||||||
|
|
||||||
// Check what was actually imported
|
// Check what was actually imported
|
||||||
const settings = await this.$accountSettings();
|
const settings = await this.$accountSettings();
|
||||||
|
console.log("[ImportAccountView] settings", JSON.stringify(settings, null, 2));
|
||||||
|
|
||||||
// Check account-specific settings
|
// Check account-specific settings
|
||||||
if (settings?.activeDid) {
|
if (settings?.activeDid) {
|
||||||
|
|||||||
@@ -1,15 +1,48 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import { importUser, generateNewEthrUser, switchToUser } from './testUtils';
|
import { switchToUser, getTestUserData } from './testUtils';
|
||||||
|
|
||||||
test('New offers for another user', async ({ page }) => {
|
test('New offers for another user', async ({ page }) => {
|
||||||
const user01Did = await generateNewEthrUser(page);
|
|
||||||
await page.goto('./');
|
await page.goto('./');
|
||||||
|
|
||||||
|
// Get the auto-created DID from the HomeView
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
const autoCreatedDid = await page.getAttribute('#Content', 'data-active-did');
|
||||||
|
console.log("[New offers for another user] Auto-created DID:", autoCreatedDid);
|
||||||
|
|
||||||
|
if (!autoCreatedDid) {
|
||||||
|
throw new Error('Auto-created DID not found in HomeView');
|
||||||
|
}
|
||||||
|
|
||||||
await page.getByTestId('closeOnboardingAndFinish').click();
|
await page.getByTestId('closeOnboardingAndFinish').click();
|
||||||
await expect(page.getByTestId('newDirectOffersActivityNumber')).toBeHidden();
|
await expect(page.getByTestId('newDirectOffersActivityNumber')).toBeHidden();
|
||||||
|
|
||||||
await importUser(page, '00');
|
// Navigate to AccountViewView to use the Identity Switcher
|
||||||
|
await page.goto('./account');
|
||||||
|
|
||||||
|
// Click "Show Advanced Settings" to reveal the identity switcher
|
||||||
|
await page.getByTestId('advancedSettings').click();
|
||||||
|
|
||||||
|
// Use the identity switcher to add User Zero
|
||||||
|
await page.locator('#switch-identity-link').click();
|
||||||
|
await page.locator('#start-link').click();
|
||||||
|
|
||||||
|
// Select "You have a seed" option
|
||||||
|
await page.getByText('You have a seed').click();
|
||||||
|
|
||||||
|
// Get User Zero's seed phrase using the new method
|
||||||
|
const userZeroData = getTestUserData('00');
|
||||||
|
|
||||||
|
// Enter User Zero's seed phrase
|
||||||
|
await page.getByPlaceholder('Seed Phrase').fill(userZeroData.seedPhrase);
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Import' }).click();
|
||||||
|
|
||||||
|
// Wait for import to complete
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
|
||||||
|
// As User Zero, add the auto-created DID as a contact
|
||||||
await page.goto('./contacts');
|
await page.goto('./contacts');
|
||||||
await page.getByPlaceholder('URL or DID, Name, Public Key').fill(user01Did + ', A Friend');
|
await page.getByPlaceholder('URL or DID, Name, Public Key').fill(autoCreatedDid + ', A Friend');
|
||||||
await expect(page.locator('button > svg.fa-plus')).toBeVisible();
|
await expect(page.locator('button > svg.fa-plus')).toBeVisible();
|
||||||
await page.locator('button > svg.fa-plus').click();
|
await page.locator('button > svg.fa-plus').click();
|
||||||
await page.locator('div[role="alert"] button:has-text("No")').click(); // don't register
|
await page.locator('div[role="alert"] button:has-text("No")').click(); // don't register
|
||||||
@@ -41,8 +74,8 @@ test('New offers for another user', async ({ page }) => {
|
|||||||
await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss info alert
|
await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss info alert
|
||||||
await expect(page.locator('div[role="alert"] button > svg.fa-xmark')).toBeHidden(); // ensure alert is gone
|
await expect(page.locator('div[role="alert"] button > svg.fa-xmark')).toBeHidden(); // ensure alert is gone
|
||||||
|
|
||||||
// as user 1, go to the home page and check that two offers are shown as new
|
// Switch back to the auto-created DID (the "another user") to see the offers
|
||||||
await switchToUser(page, user01Did);
|
await switchToUser(page, autoCreatedDid);
|
||||||
await page.goto('./');
|
await page.goto('./');
|
||||||
let offerNumElem = page.getByTestId('newDirectOffersActivityNumber');
|
let offerNumElem = page.getByTestId('newDirectOffersActivityNumber');
|
||||||
await expect(offerNumElem).toHaveText('2');
|
await expect(offerNumElem).toHaveText('2');
|
||||||
|
|||||||
@@ -1,24 +1,30 @@
|
|||||||
import { expect, Page } from '@playwright/test';
|
import { expect, Page } from '@playwright/test';
|
||||||
|
|
||||||
// Import the seed and switch to the user based on the ID.
|
// Get test user data based on the ID.
|
||||||
// '01' -> user 111
|
// '01' -> user 111
|
||||||
// otherwise -> user 000
|
// otherwise -> user 000
|
||||||
// (... which is a weird convention but I haven't taken the time to change it)
|
// (... which is a weird convention but I haven't taken the time to change it)
|
||||||
export async function importUser(page: Page, id?: string): Promise<string> {
|
export function getTestUserData(id?: string): { seedPhrase: string, userName: string, did: string } {
|
||||||
let seedPhrase, userName, did;
|
|
||||||
|
|
||||||
// Set seed phrase and DID based on user ID
|
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case '01':
|
case '01':
|
||||||
seedPhrase = 'island fever beef wine urban aim vacant quit afford total poem flame service calm better adult neither color gaze forum month sister imitate excite';
|
return {
|
||||||
userName = 'User One';
|
seedPhrase: 'island fever beef wine urban aim vacant quit afford total poem flame service calm better adult neither color gaze forum month sister imitate excite',
|
||||||
did = 'did:ethr:0x111d15564f824D56C7a07b913aA7aDd03382aA39';
|
userName: 'User One',
|
||||||
break;
|
did: 'did:ethr:0x111d15564f824D56C7a07b913aA7aDd03382aA39'
|
||||||
|
};
|
||||||
default: // to user 00
|
default: // to user 00
|
||||||
seedPhrase = 'rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage';
|
return {
|
||||||
userName = 'User Zero';
|
seedPhrase: 'rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage',
|
||||||
did = 'did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F';
|
userName: 'User Zero',
|
||||||
|
did: 'did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import the seed and switch to the user based on the ID.
|
||||||
|
export async function importUser(page: Page, id?: string): Promise<string> {
|
||||||
|
const userData = getTestUserData(id);
|
||||||
|
const { seedPhrase, userName, did } = userData;
|
||||||
|
|
||||||
// Import ID
|
// Import ID
|
||||||
await page.goto('./start');
|
await page.goto('./start');
|
||||||
@@ -109,7 +115,7 @@ export async function generateRandomString(length: number): Promise<string> {
|
|||||||
|
|
||||||
// Function to create an array of unique strings
|
// Function to create an array of unique strings
|
||||||
export async function createUniqueStringsArray(count: number): Promise<string[]> {
|
export async function createUniqueStringsArray(count: number): Promise<string[]> {
|
||||||
const stringsArray = [];
|
const stringsArray: string[] = [];
|
||||||
const stringLength = 16;
|
const stringLength = 16;
|
||||||
|
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
@@ -122,7 +128,7 @@ export async function createUniqueStringsArray(count: number): Promise<string[]>
|
|||||||
|
|
||||||
// Function to create an array of two-digit non-zero numbers
|
// Function to create an array of two-digit non-zero numbers
|
||||||
export async function createRandomNumbersArray(count: number): Promise<number[]> {
|
export async function createRandomNumbersArray(count: number): Promise<number[]> {
|
||||||
const numbersArray = [];
|
const numbersArray: number[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
let randomNumber = Math.floor(Math.random() * 99) + 1;
|
let randomNumber = Math.floor(Math.random() * 99) + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user