forked from trent_larson/crowd-funder-for-time-pwa
Fix duplicate export declarations and migrate ContactsView with sub-components
- Remove duplicate NOTIFY_INVITE_MISSING and NOTIFY_INVITE_PROCESSING_ERROR exports - Update InviteOneAcceptView.vue to use correct NOTIFY_INVITE_TRUNCATED_DATA constant - Migrate ContactsView to PlatformServiceMixin and extract into modular sub-components - Resolves TypeScript compilation errors preventing web build
This commit is contained in:
@@ -1,39 +1,3 @@
|
||||
/**
|
||||
* @fileoverview Tests for the new activity/offers system in TimeSafari
|
||||
*
|
||||
* CRITICAL UNDERSTANDING: Offer Acknowledgment System
|
||||
* ===================================================
|
||||
*
|
||||
* This file tests the offer acknowledgment mechanism, which was clarified through
|
||||
* systematic debugging investigation. Key findings:
|
||||
*
|
||||
* 1. POINTER-BASED TRACKING:
|
||||
* - TimeSafari uses `lastAckedOfferToUserJwtId` to track the last acknowledged offer
|
||||
* - Offers with IDs newer than this pointer are considered "new" and counted
|
||||
* - The UI shows count of offers newer than the pointer
|
||||
*
|
||||
* 2. TWO DISMISSAL MECHANISMS:
|
||||
* a) COMPLETE DISMISSAL (used in this test):
|
||||
* - Triggered by: Expanding offers section (clicking chevron)
|
||||
* - Method: expandOffersToUserAndMarkRead()
|
||||
* - Action: Sets lastAckedOfferToUserJwtId = newOffersToUser[0].jwtId (newest)
|
||||
* - Result: ALL offers marked as read, count becomes 0 (hidden)
|
||||
*
|
||||
* b) SELECTIVE DISMISSAL:
|
||||
* - Triggered by: Clicking "Keep all above as new offers"
|
||||
* - Method: markOffersAsReadStartingWith(jwtId)
|
||||
* - Action: Sets lastAckedOfferToUserJwtId = nextOffer.jwtId (partial)
|
||||
* - Result: Only offers above clicked offer marked as read
|
||||
*
|
||||
* 3. BROWSER COMPATIBILITY:
|
||||
* - Initially appeared to be Chromium-specific issue
|
||||
* - Investigation revealed test logic error, not browser incompatibility
|
||||
* - Both Chromium and Firefox now pass consistently
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @since Investigation completed 2024-12-27
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { importUser, generateNewEthrUser, switchToUser } from './testUtils';
|
||||
|
||||
@@ -48,21 +12,13 @@ test('New offers for another user', async ({ page }) => {
|
||||
await page.getByPlaceholder('URL or DID, Name, Public Key').fill(user01Did + ', A Friend');
|
||||
await expect(page.locator('button > svg.fa-plus')).toBeVisible();
|
||||
await page.locator('button > svg.fa-plus').click();
|
||||
|
||||
// The alert shows "SuccessThey were added." not "Contact Added"
|
||||
await expect(page.locator('div[role="alert"]')).toContainText('They were added');
|
||||
|
||||
// Check if registration prompt appears (it may not if user is not registered)
|
||||
const noButtonCount = await page.locator('div[role="alert"] button:has-text("No")').count();
|
||||
if (noButtonCount > 0) {
|
||||
await page.locator('div[role="alert"] button:has-text("No")').click(); // don't register
|
||||
}
|
||||
|
||||
await expect(page.locator('div[role="alert"] span:has-text("Contact Added")')).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
|
||||
|
||||
// show buttons to make offers directly to people
|
||||
await page.getByRole('button').filter({ hasText: /See Actions/i }).click();
|
||||
await page.getByRole('button').filter({ hasText: /See Hours/i }).click();
|
||||
|
||||
// make an offer directly to user 1
|
||||
// Generate a random string of 3 characters, skipping the "0." at the beginning
|
||||
@@ -88,13 +44,11 @@ test('New offers for another user', async ({ page }) => {
|
||||
// as user 1, go to the home page and check that two offers are shown as new
|
||||
await switchToUser(page, user01Did);
|
||||
await page.goto('./');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
let offerNumElemForTest = page.getByTestId('newDirectOffersActivityNumber');
|
||||
await expect(offerNumElemForTest).toHaveText('2');
|
||||
let offerNumElem = page.getByTestId('newDirectOffersActivityNumber');
|
||||
await expect(offerNumElem).toHaveText('2');
|
||||
|
||||
// click on the number of new offers to go to the list page
|
||||
await offerNumElemForTest.click();
|
||||
await offerNumElem.click();
|
||||
|
||||
await expect(page.getByText('New Offers To You', { exact: true })).toBeVisible();
|
||||
await page.getByTestId('showOffersToUser').locator('div > svg.fa-chevron-right').click();
|
||||
@@ -102,32 +56,28 @@ test('New offers for another user', async ({ page }) => {
|
||||
await expect(page.getByText(`help of ${randomString2} from #000`)).toBeVisible();
|
||||
await expect(page.getByText(`help of ${randomString1} from #000`)).toBeVisible();
|
||||
|
||||
/**
|
||||
* OFFER ACKNOWLEDGMENT MECHANISM:
|
||||
*
|
||||
* TimeSafari uses a pointer-based system to track which offers are "new":
|
||||
* - `lastAckedOfferToUserJwtId` stores the ID of the last acknowledged offer
|
||||
* - Offers newer than this pointer are considered "new" and counted
|
||||
*
|
||||
* Two dismissal mechanisms exist:
|
||||
* 1. COMPLETE DISMISSAL: Expanding the offers section calls expandOffersToUserAndMarkRead()
|
||||
* which sets lastAckedOfferToUserJwtId = newOffersToUser[0].jwtId (newest offer)
|
||||
* Result: ALL offers marked as read, count goes to 0
|
||||
*
|
||||
* 2. SELECTIVE DISMISSAL: "Keep all above" calls markOffersAsReadStartingWith(jwtId)
|
||||
* which sets lastAckedOfferToUserJwtId = nextOffer.jwtId (partial dismissal)
|
||||
* Result: Only offers above the clicked offer are marked as read
|
||||
*
|
||||
* This test uses mechanism #1 (expansion) for complete dismissal.
|
||||
* The expansion already happened when we clicked the chevron above.
|
||||
*/
|
||||
// click on the latest offer to keep it as "unread"
|
||||
await page.hover(`li:has-text("help of ${randomString2} from #000")`);
|
||||
// await page.locator('li').filter({ hasText: `help of ${randomString2} from #000` }).click();
|
||||
// await page.locator('div').filter({ hasText: /keep all above/ }).click();
|
||||
// now find the "Click to keep all above as new offers" after that list item and click it
|
||||
const liElem = page.locator('li').filter({ hasText: `help of ${randomString2} from #000` });
|
||||
await liElem.hover();
|
||||
const keepAboveAsNew = await liElem.locator('div').filter({ hasText: /keep all above/ });
|
||||
|
||||
// now see that all offers are dismissed since we expanded the section
|
||||
await keepAboveAsNew.click();
|
||||
|
||||
// now see that only one offer is shown as new
|
||||
await page.goto('./');
|
||||
await page.waitForLoadState('networkidle');
|
||||
offerNumElem = page.getByTestId('newDirectOffersActivityNumber');
|
||||
await expect(offerNumElem).toHaveText('1');
|
||||
await offerNumElem.click();
|
||||
await expect(page.getByText('New Offer To You', { exact: true })).toBeVisible();
|
||||
await page.getByTestId('showOffersToUser').locator('div > svg.fa-chevron-right').click();
|
||||
|
||||
// now see that no offers are shown as new
|
||||
await page.goto('./');
|
||||
// wait until the list with ID listLatestActivity has at least one visible item
|
||||
await page.locator('#listLatestActivity li').first().waitFor({ state: 'visible' });
|
||||
|
||||
await expect(page.getByTestId('newDirectOffersActivityNumber')).toBeHidden();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user