import { test, expect } from '@playwright/test'; import { importUser } from './testUtils'; test('Add contact, record gift, confirm gift', async ({ page }) => { // Generate a random string of 16 characters let randomString = Math.random().toString(36).substring(2, 18); // In case the string is shorter than 16 characters, generate more characters until it is 16 characters long while (randomString.length < 16) { randomString += Math.random().toString(36).substring(2, 18); } const finalRandomString = randomString.substring(0, 16); // Generate a random non-zero single-digit number const randomNonZeroNumber = Math.floor(Math.random() * 99) + 1; // Standard title prefix const standardTitle = 'Gift '; // Combine title prefix with the random string const finalTitle = standardTitle + finalRandomString; // Contact name const contactName = 'Contact #000 renamed'; // Import user 01 await importUser(page, '01'); // Add new contact await page.goto('./contacts'); await page.getByPlaceholder('URL or DID, Name, Public Key').fill('did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F, User #000'); await page.locator('button > svg.fa-plus').click(); await expect(page.locator('div[role="alert"]')).toBeVisible(); await page.locator('div[role="alert"] button:has-text("No")').click(); // don't register 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 // Verify added contact await expect(page.locator('li.border-b')).toContainText('User #000'); // Rename contact await page.locator('li.border-b div div > a[title="See more about this person"]').click(); await page.locator('h2 > button > svg.fa-pen').click(); await expect(page.locator('div.dialog-overlay > div.dialog').filter({ hasText: 'Edit Name' })).toBeVisible(); await page.getByPlaceholder('Name', { exact: true }).fill(contactName); await page.locator('.dialog > .flex > button').first().click(); // await page.locator('.dialog > .flex > button').first().click(); // close alert // Confirm that home shows contact in "Record Something…" await page.goto('./'); await expect(page.locator('#sectionRecordSomethingGiven ul li').filter({ hasText: contactName }).nth(0)).toBeVisible(); // Record something given by new contact await page.getByRole('heading', { name: contactName }).click(); await page.getByPlaceholder('What was given').fill(finalTitle); await page.getByRole('spinbutton').fill(randomNonZeroNumber.toString()); await page.getByRole('button', { name: 'Sign & Send' }).click(); await expect(page.getByText('That gift was recorded.')).toBeVisible(); // Refresh home view and check gift await page.goto('./'); // Firefox complains on load the initial feed here when we use the test server. // It may be similar to the CORS problem below. await page.locator('li').filter({ hasText: finalTitle }).locator('a').click(); await expect(page.getByRole('heading', { name: 'Verifiable Claim Details' })).toBeVisible(); await expect(page.getByText(finalTitle, { exact: true })).toBeVisible(); // Switch to user 00 await page.goto('./account'); await page.getByRole('heading', { name: 'Advanced' }).click(); await page.getByRole('link', { name: 'Switch Identifier' }).click(); await page.getByRole('link', { name: 'Add Another Identity…' }).click(); await page.getByText('You have a seed').click(); await page.getByPlaceholder('Seed Phrase').fill('rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage'); await page.getByRole('button', { name: 'Import' }).click(); // Go to home view and look for gift await page.goto('./'); await page.locator('li').filter({ hasText: finalTitle }).locator('a').click(); // Confirm gift as user 00 await page.getByTestId('confirmGiftLink').click(); await page.getByRole('button', { name: 'Confirm' }).click(); await page.getByRole('button', { name: 'Yes' }).click(); await expect(page.getByText('Confirmation submitted.')).toBeVisible(); // Refresh claim page, Confirm button should throw an alert because they already confirmed await page.reload(); await page.getByRole('button', { name: 'Confirm' }).click(); await expect(page.locator('div[role="alert"]')).toBeVisible(); }); test('Without being registered, add contacts without registration', async ({ page, context }) => { await page.goto('./account'); // wait until the DID shows on the page in the 'did' element const didElem = await page.getByTestId('didWrapper').locator('code'); const newDid = await didElem.innerText(); expect(newDid.trim()).toEqual(''); // Add new contact without registering await page.goto('./contacts'); await page.getByPlaceholder('URL or DID, Name, Public Key').fill('did:ethr:0x111d15564f824D56C7a07b913aA7aDd03382aA39, User #111'); await page.locator('button > svg.fa-plus').click(); await expect(page.locator('div[role="alert"] span:has-text("Contact Added")')).toBeVisible(); await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss info alert // wait for the alert to disappear, which also ensures that there is no "Register" button waiting await expect(page.locator('div[role="alert"]')).toBeHidden(); }); test('Add contact, copy details, delete, and import various ways', async ({ page, context }) => { await importUser(page, '00'); // Add new contact await page.goto('./contacts'); await page.getByPlaceholder('URL or DID, Name, Public Key').fill('did:ethr:0x111d15564f824D56C7a07b913aA7aDd03382aA39, User #111'); await page.locator('button > svg.fa-plus').click(); await expect(page.locator('div[role="alert"]')).toBeVisible(); await page.locator('div[role="alert"] button:has-text("No")').click(); // don't register await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss info alert // wait for the alert to disappear await expect(page.locator('div[role="alert"]')).toBeHidden(); // Add another new contact await page.getByPlaceholder('URL or DID, Name, Public Key').fill('did:ethr:0x222BB77E6Ff3774d34c751f3c1260866357B677b, User #222, asdf1234'); await page.locator('button > svg.fa-plus').click(); await expect(page.locator('div[role="alert"]')).toBeVisible(); await page.locator('div[role="alert"] button:has-text("No")').click(); // don't register await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss info alert await expect(page.locator('div[role="alert"]')).toBeHidden(); await expect(page.getByTestId('contactListItem')).toHaveCount(2); //// Copy contact details, export them, remove them, and paste to add them // Copy contact details await page.getByTestId('contactCheckAllTop').click(); await page.getByTestId('copySelectedContactsButtonTop').click(); await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss alert await expect(page.locator('div[role="alert"]')).toBeHidden(); // I would prefer to copy from the clipboard, but the recommended approaches don't work. // this seems to fail in non-chromium browsers //await context.grantPermissions(['clipboard-read', 'clipboard-write']); // this seems to fail in chromium (at least) where clipboard is undefined //const contactData = await navigator.clipboard.readText(); // see contact details on the second contact await page.getByTestId('contactListItem').nth(1).locator('a').click(); await page.getByRole('heading', { name: 'Identifier Details' }).isVisible(); // remove 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(); // Firefox has a problem when we run this against the test server. It doesn't load the feed. // It says there's a CORS problem; maybe it's more strict than the other browsers. // It works when we set the config to use a local server. // Seems like we hit a similar problem above. await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss alert await expect(page.locator('div[role="alert"]')).toBeHidden(); // go to the contacts page and paste the copied contact details await page.goto('./contacts'); // check that there are fewer contacts await expect(page.getByTestId('contactListItem')).toHaveCount(1); const contactData = 'Paste this: [{ "did": "did:ethr:0x111d15564f824D56C7a07b913aA7aDd03382aA39", "name": "User #111" }, { "did": "did:ethr:0x222BB77E6Ff3774d34c751f3c1260866357B677b", "name": "User #222", "publicKeyBase64": "asdf1234"}] ' await page.getByPlaceholder('URL or DID, Name, Public Key').fill(contactData); await page.locator('button > svg.fa-plus').click(); // we're on the contact-import page await expect(page.locator('li', { hasText: 'New' })).toHaveCount(1); await expect(page.locator('span').filter({ hasText: 'the same as' })).toBeVisible(); await page.locator('button', { hasText: 'Import' }).click(); // check that there are more contacts await expect(page.getByTestId('contactListItem')).toHaveCount(2); // Import via the file backup-import await page.goto('./account'); await page.getByRole('heading', { name: 'Advanced' }).click(); const fileSelect = await page.locator('input[type="file"]') //fileSelect.click(); fileSelect.setInputFiles('./test-playwright/exported-data.json'); await page.locator('button', { hasText: 'Import Only Contacts' }).click(); // we're on the contact-import page await expect(page.locator('li', { hasText: '- New' })).toHaveCount(3); await expect(page.locator('li', { hasText: '- Existing' })).toHaveCount(1); await expect(page.locator('span').filter({ hasText: 'the same as' })).toBeHidden(); await page.locator('button', { hasText: 'Import' }).click(); // check that there are more contacts await expect(page.getByTestId('contactListItem')).toHaveCount(5); // The visibility error is because currently the server returns an error for the same person. // But it should only show that one, for User #000. });