import { expect, Page } from "@playwright/test"; // Get test user data based on the ID. // '01' -> user 111 // otherwise -> user 000 // (... which is a weird convention but I haven't taken the time to change it) export function getTestUserData(id?: string): { seedPhrase: string; userName: string; did: string; } { switch (id) { case "01": return { 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", userName: "User One", did: "did:ethr:0x111d15564f824D56C7a07b913aA7aDd03382aA39", }; default: // to user 00 return { 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", userName: "User Zero", did: "did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F", }; } } export async function importUserFromAccount(page: Page, id?: string): Promise { // 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(id); // 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"); return userZeroData.did; } // Import the seed and switch to the user based on the ID. export async function importUser(page: Page, id?: string): Promise { const userData = getTestUserData(id); const { seedPhrase, userName, did } = userData; // Import ID await page.goto("./start"); await page.getByText("You have a seed").click(); await page.getByPlaceholder("Seed Phrase").fill(seedPhrase); await page.getByRole("button", { name: "Import" }).click(); // Check DID await expect(page.getByRole("code")).toContainText(did); // ... and ensure the app retrieves the registration status await expect( page.locator("#sectionUsageLimits").getByText("Checking") ).toBeHidden(); return did; } export async function importUserAndCloseOnboarding( page: Page, id?: string ): Promise { const did = await importUser(page, id); await page.goto("./"); await page.getByTestId("closeOnboardingAndFinish").click(); return did; } // This is to switch to someone already in the identity table. It doesn't include registration. export async function switchToUser(page: Page, did: string): Promise { // This is the direct approach but users have to tap on things so we'll do that instead. //await page.goto('./identity-switcher'); await page.goto("./account"); // Wait for the page to load and the advanced settings element to be visible await page.waitForLoadState('networkidle'); await page.getByTestId("advancedSettings").waitFor({ state: 'visible' }); const switchIdentityLink = page.locator("#switch-identity-link"); if (await switchIdentityLink.isHidden()) { await page.getByTestId("advancedSettings").click(); await switchIdentityLink.click(); } else { await switchIdentityLink.click(); } const didElem = await page.locator(`code:has-text("${did}")`); await didElem.isVisible(); await didElem.click(); // wait for the switch to happen and the account page to fully load await page.getByTestId("didWrapper").locator('code:has-text("did:")'); } function createContactName(did: string): string { return "User " + did.slice(11, 14); } export async function deleteContact(page: Page, did: string): Promise { await page.goto("./contacts"); const contactName = createContactName(did); // go to the detail page for this contact await page .locator( `li[data-testid="contactListItem"] h2:has-text("${contactName}") + div svg.fa-circle-info` ) .click(); // delete the contact await page.locator("button > svg.fa-trash-can").click(); await page.locator('div[role="alert"] button:has-text("Yes")').click(); // for some reason, .isHidden() (without expect) doesn't work await expect( page.locator('div[role="alert"] button:has-text("Yes")') ).toBeHidden(); } export async function generateNewEthrUser(page: Page): Promise { await page.goto("./start"); await page.getByTestId("newSeed").click(); await expect(page.locator('span:has-text("Created")')).toBeVisible(); await page.goto("./account"); const didElem = await page .getByTestId("didWrapper") .locator('code:has-text("did:")'); const newDid = await didElem.innerText(); return newDid; } // Generate a new random user and register them. // Note that this makes 000 the active user. Use switchToUser to switch to this DID. export async function generateAndRegisterEthrUser(page: Page): Promise { const newDid = await generateNewEthrUser(page); await importUser(page, "000"); // switch to user 000 await page.goto("./contacts"); const contactName = createContactName(newDid); await page .getByPlaceholder("URL or DID, Name, Public Key") .fill(`${newDid}, ${contactName}`); await page.locator("button > svg.fa-plus").click(); // register them await page.locator('div[role="alert"] button:has-text("Yes")').click(); // wait for it to disappear because the next steps may depend on alerts being gone await expect( page.locator('div[role="alert"] button:has-text("Yes")') ).toBeHidden(); await expect(page.locator("li", { hasText: contactName })).toBeVisible(); return newDid; } // Function to generate a random string of specified length export async function generateRandomString(length: number): Promise { return Math.random() .toString(36) .substring(2, 2 + length); } // Function to create an array of unique strings export async function createUniqueStringsArray( count: number ): Promise { const stringsArray: string[] = []; const stringLength = 16; for (let i = 0; i < count; i++) { let randomString = await generateRandomString(stringLength); stringsArray.push(randomString); } return stringsArray; } // Function to create an array of two-digit non-zero numbers export async function createRandomNumbersArray( count: number ): Promise { const numbersArray: number[] = []; for (let i = 0; i < count; i++) { let randomNumber = Math.floor(Math.random() * 99) + 1; numbersArray.push(randomNumber); } return numbersArray; } export function isLinuxEnvironment() { return process.platform === "linux"; } export function getOSSpecificTimeout(): number { // Increase base timeout for Linux const isLinux = process.platform === "linux"; return isLinux ? 180000 : 60000; // 3 minutes for Linux, 1 minute for others } export function getOSSpecificConfig() { if (isLinuxEnvironment()) { return { retries: 2, timeout: 90000, // Increased global timeout expect: { timeout: 30000, // Increased expect timeout }, // Add video recording for failed tests on Linux use: { video: "retain-on-failure", trace: "retain-on-failure", }, }; } return {}; } // Add helper for test grouping export function isResourceIntensiveTest(testPath: string): boolean { return ( testPath.includes("35-record-gift-from-image-share") || testPath.includes("40-add-contact") ); }