You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							219 lines
						
					
					
						
							8.2 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							219 lines
						
					
					
						
							8.2 KiB
						
					
					
				| /** | |
|  * Initial State and Basic Functionality Tests | |
|  *  | |
|  * Core test suite that validates fundamental application features and initial state handling. | |
|  * These tests run first to ensure basic functionality before more complex tests. | |
|  *  | |
|  * Test Categories: | |
|  * 1. Activity Feed | |
|  *    - Verifies server connectivity | |
|  *    - Tests infinite scroll loading | |
|  *    - Checks initial 10 activities load | |
|  *    - Validates additional activity loading | |
|  *  | |
|  * 2. Discovery Features | |
|  *    - Tests project listing | |
|  *    - Verifies infinite scroll | |
|  *    - Checks project card rendering | |
|  *  | |
|  * 3. Account State | |
|  *    - Validates initial no-ID state | |
|  *    - Tests ID generation flow | |
|  *    - Verifies registration notices | |
|  *    - Checks account detail display | |
|  *  | |
|  * 4. Contact Sharing | |
|  *    - Tests name setting functionality | |
|  *    - Validates clipboard operations | |
|  *    - Checks sharing UI elements | |
|  *    - Verifies alert handling | |
|  *  | |
|  * 5. User Registration | |
|  *    - Tests User 0's ability to register others | |
|  *    - Validates gift recording after registration | |
|  *    - Checks contact deletion | |
|  *    - Verifies deleted contact handling | |
|  *  | |
|  * Key Selectors: | |
|  * - Activity list: 'ul#listLatestActivity li' | |
|  * - Discover list: 'ul#listDiscoverResults li' | |
|  * - Account notices: '#noticeBeforeShare', '#noticeSomeoneMustRegisterYou' | |
|  * - Identity details: '#sectionIdentityDetails code.truncate' | |
|  *  | |
|  * State Verification: | |
|  * - Checks empty ID state | |
|  * - Verifies ID generation | |
|  * - Validates alert presence/dismissal | |
|  * - Confirms navigation state | |
|  *  | |
|  * Alert Handling: | |
|  * - Closes onboarding dialogs | |
|  * - Verifies alert content | |
|  * - Checks alert dismissal | |
|  * - Validates alert transitions | |
|  *  | |
|  * Important Checks: | |
|  * - Server connectivity | |
|  * - Data loading | |
|  * - UI state transitions | |
|  * - Error conditions | |
|  * - Clipboard operations | |
|  *  | |
|  * @example Checking activity feed | |
|  * ```typescript | |
|  * await page.goto('./'); | |
|  * await page.getByTestId('closeOnboardingAndFinish').click(); | |
|  * await expect(page.locator('ul#listLatestActivity li:nth-child(10)')) | |
|  *   .toBeVisible(); | |
|  * ``` | |
|  */ | |
| 
 | |
| import { test, expect } from '@playwright/test'; | |
| import { UNNAMED_ENTITY_NAME } from '../src/constants/entities'; | |
| import { deleteContact, generateAndRegisterEthrUser, importUser } from './testUtils'; | |
| import { NOTIFY_CONTACT_INVALID_DID } from '../src/constants/notifications'; | |
| 
 | |
| test('Check activity feed - check that server is running', async ({ page }) => { | |
|   // Load app homepage | |
|   await page.goto('./'); | |
|   await page.getByTestId('closeOnboardingAndFinish').click(); | |
| 
 | |
|   // Check that initial 10 activities have been loaded | |
|   await expect(page.locator('ul#listLatestActivity li:nth-child(10)')).toBeVisible(); | |
| 
 | |
|   // Scroll down a bit to trigger loading additional activities | |
|   await page.locator('ul#listLatestActivity li:nth-child(50)').scrollIntoViewIfNeeded(); | |
| }); | |
| 
 | |
| test('Check discover results', async ({ page }) => { | |
|   // Load Discover view | |
|   await page.goto('./discover'); | |
| 
 | |
|   // Check that initial 10 projects have been loaded | |
|   await expect(page.locator('ul#listDiscoverResults li.border-b:nth-child(10)')).toBeVisible(); | |
| 
 | |
|   // Scroll down a bit to trigger loading additional projects | |
|   await page.locator('ul#listDiscoverResults li.border-b:nth-child(20)').scrollIntoViewIfNeeded(); | |
| }); | |
| 
 | |
| test('Check no-ID messaging in account', async ({ page }) => { | |
|   // Load account view | |
|   await page.goto('./account'); | |
| 
 | |
|   // Check 'a friend needs to register you' notice | |
|   await expect(page.locator('#noticeSomeoneMustRegisterYou')).toBeVisible(); | |
| }); | |
| 
 | |
| test('Check ability to share contact', async ({ page }) => { | |
|   // Load Discover view | |
|   await page.goto('./discover'); | |
| 
 | |
|   // Check that initial 10 projects have been loaded | |
|   await expect(page.locator('ul#listDiscoverResults li.border-b:nth-child(10)')).toBeVisible(); | |
| 
 | |
|   // Scroll down a bit to trigger loading additional projects | |
|   await page.locator('ul#listDiscoverResults li.border-b:nth-child(20)').scrollIntoViewIfNeeded(); | |
| }); | |
| 
 | |
| test('Check ID generation', async ({ page }) => { | |
|   // Load homepage to trigger ID generation (?) | |
|   await page.goto('./'); | |
| 
 | |
|   // Wait for activity feed to start loading, as a delay | |
|   await expect(page.locator('ul#listLatestActivity li:nth-child(10)')).toBeVisible(); | |
| 
 | |
|   // Check 'someone must register you' notice | |
|   await expect(page.getByText('To share, someone must register you.')).toBeVisible(); | |
| 
 | |
|   // Go back to Account view | |
|   await page.goto('./account'); | |
| 
 | |
|   // Check that ID is now generated | |
|   await expect(page.locator('#sectionIdentityDetails code.truncate')).toContainText('did:ethr:'); | |
| }); | |
| 
 | |
| 
 | |
| test('Check setting name & sharing info', async ({ page }) => { | |
|   // Load homepage to trigger ID generation (?) | |
|   await page.goto('./'); | |
|   await page.getByTestId('closeOnboardingAndFinish').click(); | |
|   // Check 'someone must register you' notice | |
|   await expect(page.getByText('someone must register you.')).toBeVisible(); | |
|   await page.getByRole('button', { name: /Show them/}).click(); | |
|   // fill in a name | |
|   await expect(page.getByText('Set Your Name')).toBeVisible(); | |
|   await page.getByRole('textbox').fill('Me Test User'); | |
|   await page.locator('button:has-text("Save")').click(); | |
|   await expect(page.getByText('share some other way')).toBeVisible(); | |
|   await page.getByRole('button', { name: /share some other way/ }).click(); | |
|   await expect(page.getByRole('button', { name: 'Copy contact information to' })).toBeVisible(); | |
|   await page.getByRole('button', { name: 'Copy contact information to' }).click(); | |
|   await expect(page.getByText('contact info was copied')).toBeVisible(); | |
|   // wait for alert to go away | |
|   await expect(page.getByText('contact info was copied')).toBeHidden({ timeout: 10000 }); | |
|   // check that they're on the Contacts screen | |
|   await expect(page.getByText('your contacts')).toBeVisible(); | |
| }); | |
| 
 | |
| test('Confirm test API setting (may fail if you are running your own Time Safari)', async ({ page }, testInfo) => { | |
|   // Load account view | |
|   await page.goto('./account'); | |
|   await page.getByTestId('advancedSettings').click(); | |
| 
 | |
|   // look into the config file: if it starts Time Safari, it might say which server it should set by default | |
|   const webServer = testInfo.config.webServer; | |
|   const endorserWords = webServer?.command.split(' '); | |
|   const ENDORSER_ENV_NAME = 'VITE_DEFAULT_ENDORSER_API_SERVER'; | |
|   const endorserTerm = endorserWords?.find(word => word.startsWith(ENDORSER_ENV_NAME + '=')); | |
|   const endorserTermInConfig = endorserTerm?.substring(ENDORSER_ENV_NAME.length + 1); | |
| 
 | |
|   const endorserServer = endorserTermInConfig || 'https://test-api.endorser.ch'; | |
|   await expect(page.locator('#apiServerInput')).toHaveValue(endorserServer); | |
| }); | |
| 
 | |
| test('Check invalid DID shows error and redirects', async ({ page }) => { | |
|   await importUser(page, '00'); | |
|    | |
|   // Navigate to an invalid DID URL | |
|   await page.goto('./did/0'); | |
|    | |
|   // Should show error message about invalid DID format | |
|   await expect(page.getByText(NOTIFY_CONTACT_INVALID_DID.message)).toBeVisible(); | |
|    | |
|   // Should redirect to homepage | |
|   await expect(page).toHaveURL(/.*\/$/); | |
| }); | |
| 
 | |
| test('Check User 0 can register a random person', async ({ page }) => { | |
|   await importUser(page, '00'); | |
|   const newDid = await generateAndRegisterEthrUser(page); | |
|   expect(newDid).toContain('did:ethr:'); | |
| 
 | |
|   await page.goto('./'); | |
|   await page.getByTestId('closeOnboardingAndFinish').click(); | |
|   await page.getByRole('button', { name: 'Person' }).click(); | |
|       await page.getByRole('listitem').filter({ hasText: UNNAMED_ENTITY_NAME }).locator('svg').click(); | |
|   await page.getByPlaceholder('What was given').fill('Gave me access!'); | |
|   await page.getByRole('button', { name: 'Sign & Send' }).click(); | |
|   await expect(page.getByText('That gift was recorded.')).toBeVisible(); | |
|   // now ensure that alert goes away | |
|   await page.locator('div[role="alert"] button > svg.fa-xmark').click(); // dismiss alert | |
|   await expect(page.getByText('That gift was recorded.')).toBeHidden(); | |
| 
 | |
|   // now delete the contact to test that pages still do reasonable things | |
|   await deleteContact(page, newDid); | |
|   // go the activity page for this new person | |
|   await page.goto('./did/' + encodeURIComponent(newDid)); | |
|   // maybe replace by: const popupPromise = page.waitForEvent('popup'); | |
|   let error; | |
|   try { | |
|     await page.waitForSelector('div[role="alert"]', { timeout: 2000 }); | |
|     error = new Error('Error alert should not show.'); | |
|   } catch (error) { | |
|     // success | |
|   } finally { | |
|     if (error) { | |
|       throw error; | |
|     } | |
|   } | |
| });
 | |
| 
 |