Browse Source

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.
pull/142/head
Matthew Raymer 3 days ago
parent
commit
9c3d2792ae
  1. 1
      src/services/platforms/WebPlatformService.ts
  2. 1
      src/utils/PlatformServiceMixin.ts
  3. 14
      src/views/ContactsView.vue
  4. 2
      src/views/HomeView.vue
  5. 2
      src/views/ImportAccountView.vue
  6. 45
      test-playwright/60-new-activity.spec.ts
  7. 34
      test-playwright/testUtils.ts

1
src/services/platforms/WebPlatformService.ts

@ -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);
} }

1
src/utils/PlatformServiceMixin.ts

@ -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(

14
src/views/ContactsView.vue

@ -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);
} }

2
src/views/HomeView.vue

@ -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>

2
src/views/ImportAccountView.vue

@ -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) {

45
test-playwright/60-new-activity.spec.ts

@ -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');

34
test-playwright/testUtils.ts

@ -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;

Loading…
Cancel
Save