domain project / social-media

Social Media Platform

Test strategies for feeds, post creation, reactions, comments, direct messaging, notifications, and content moderation.

Feed renderingPost creation & media uploadReactions & commentsDirect messagingNotificationsContent moderation

Domain Overview

Social media platforms combine high-concurrency real-time features (feeds, DMs, notifications) with rich media pipelines (image/video upload, transcoding) and safety systems (moderation, reporting). Testing must handle eventual consistency, WebSocket-driven updates, and complex user-interaction graphs.

Typical stack: React / Vue SPA, GraphQL or REST API, Redis pub/sub for real-time, S3-compatible object storage with CDN, background job queue for media processing.

Key Test Areas

AreaWhat to testRisk
FeedInfinite scroll, chronological vs algorithmic order, empty state, sponsored postsDuplicate posts, broken pagination
Post creationText, image upload, video, hashtags, mentions, character limitMedia not attached, silent failure
EngagementLike, comment, share, reply threading, nested comment depthWrong counts, broken threads
Direct messagingReal-time delivery, read receipts, media in DMs, group DMsMessage lost, wrong recipient
NotificationsPush, in-app badge, email digest, mark-all-readStale badge count, duplicate alerts
ModerationReport content, hide, appeal decision, escalateHarmful content stays up, false positive

Test Pyramid for Social Media

Unit (60%):   Feed ranking algorithm, character count, mention parsing, notification rules
Integration (30%): Upload pipeline, push notification dispatch, moderation queue API
E2E (10%):    Create post → see in feed → receive notification → DM author

Critical E2E tests (must pass before every deploy):

  1. Create a text post and verify it appears in follower’s feed
  2. Upload an image, verify it renders correctly in the post
  3. Send a DM, verify delivery and read receipt
  4. Report a post, verify it enters moderation queue
  5. Notification badge decrements after reading notifications

Common Failure Scenarios

1. Feed duplicates posts on infinite scroll pagination boundary
   Test: scroll to page boundary, continue scrolling, assert no duplicate post IDs in DOM

2. Image upload succeeds but preview broken (CORS or presigned URL expiry)
   Test: upload image, intercept the presigned URL request, verify img src loads (no 403/CORS error)

3. Notification badge count doesn't reset on read
   Test: generate notification, read it, assert badge count is 0 not prior value

4. Mention autocomplete doesn't work with special characters in username
   Test: type '@user.name-test', assert autocomplete suggestion appears and resolves correctly

5. DM delivered to wrong user in a group context
   Test: two-context test — user A sends DM to user B in a group; assert user C's DM inbox is empty

Playwright Patterns for Social Media

// Infinite scroll — scroll and wait for API response
test('feed loads more posts on scroll without duplicates', async ({ page }) => {
  const seenIds = new Set<string>();
  await page.goto('/feed');
  // Collect initial post IDs
  const initialPosts = await page.locator('[data-post-id]').all();
  for (const post of initialPosts) {
    seenIds.add(await post.getAttribute('data-post-id') ?? '');
  }
  // Trigger next page load
  await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
  await page.waitForResponse('**/api/feed*');
  const allPosts = await page.locator('[data-post-id]').all();
  for (const post of allPosts) {
    const id = await post.getAttribute('data-post-id') ?? '';
    expect(seenIds.has(id) && allPosts.indexOf(post) >= initialPosts.length).toBe(false);
  }
});

// Mock WebSocket for real-time DM test
test('DM appears instantly via WebSocket', async ({ page }) => {
  await page.goto('/messages/thread/42');
  // Inject a mock WS message after page load
  await page.evaluate(() => {
    const event = new MessageEvent('message', {
      data: JSON.stringify({ type: 'new_message', id: 'msg-99', text: 'Hello from mock', senderId: 7 })
    });
    (window as any).__mockWsDispatch?.(event);
  });
  await expect(page.getByTestId('message-msg-99')).toBeVisible();
});