forked from jsnbuchanan/crowd-funder-for-time-pwa
- Add detailed header documentation to playwright tests - Document test categories and flows - Add key selector documentation - Document state verification and alert handling - Include code examples and usage patterns - Add important checks and requirements The documentation helps developers understand the foundational tests that verify basic application functionality before running more complex test suites.
217 lines
8.0 KiB
TypeScript
217 lines
8.0 KiB
TypeScript
/**
|
|
* 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', '#noticeBeforeAnnounce'
|
|
* - 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 { deleteContact, generateAndRegisterEthrUser, importUser } from './testUtils';
|
|
|
|
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 'someone must register you' notice
|
|
await expect(page.locator('#noticeBeforeShare')).toBeVisible();
|
|
|
|
// Check 'a friend needs to register you' notice
|
|
await expect(page.locator('#noticeBeforeAnnounce')).toBeVisible();
|
|
|
|
// Check that there is no ID
|
|
await expect(page.locator('#sectionIdentityDetails code.truncate')).toBeEmpty();
|
|
});
|
|
|
|
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 Account view
|
|
await page.goto('./account');
|
|
|
|
// Check that ID is empty
|
|
await expect(page.locator('#sectionIdentityDetails code.truncate')).toBeEmpty();
|
|
|
|
// 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 to clipboard' })).toBeVisible();
|
|
await page.getByRole('button', { name: 'copy to clipboard' }).click();
|
|
await expect(page.getByText('contact info was copied')).toBeVisible();
|
|
// dismiss alert and wait for it to go away
|
|
await page.locator('div[role="alert"] button > svg.fa-xmark').click();
|
|
await expect(page.getByText('contact info was copied')).toBeHidden();
|
|
// 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.getByRole('heading', { name: 'Advanced' }).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.getByRole('textbox').nth(1)).toHaveValue(endorserServer);
|
|
});
|
|
|
|
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('heading', { name: 'Unnamed/Unknown' }).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;
|
|
}
|
|
}
|
|
});
|