Back to Repositories

Testing gRPC Communication Patterns in Insomnia

This test suite validates gRPC interaction functionality in Insomnia, covering unidirectional, bidirectional, client streaming, and server streaming requests. It ensures reliable communication between the client and server while verifying response status codes and message content.

Test Coverage Overview

The test suite provides comprehensive coverage of gRPC communication patterns.

Key areas tested include:
  • Unidirectional request-response flows
  • Bidirectional streaming with multiple messages
  • Client-side streaming capabilities
  • Server-side streaming functionality
  • Response status validation
  • Message content verification

Implementation Analysis

The testing approach utilizes Playwright’s powerful testing framework with TypeScript. The implementation follows a structured pattern using page objects and locators for reliable element interaction.

Technical patterns include:
  • Fixture-based test data loading
  • Clipboard interaction for test setup
  • Async/await patterns for handling stream operations
  • Dynamic response validation

Technical Details

Testing infrastructure includes:
  • Playwright test runner and assertions
  • TypeScript for type safety
  • Custom fixtures for gRPC setup
  • Platform-specific test configurations
  • Locator patterns for UI element interaction
  • beforeEach hooks for test isolation

Best Practices Demonstrated

The test suite exemplifies high-quality testing practices through careful organization and robust implementation.

Notable practices include:
  • Isolated test scenarios with proper setup/teardown
  • Clear test case organization by gRPC pattern
  • Consistent assertion patterns
  • Platform-aware test configuration
  • Reusable locator definitions
  • Descriptive test case naming

kong/insomnia

packages/insomnia-smoke-test/tests/smoke/grpc-interactions.test.ts

            
import { expect, Locator } from '@playwright/test';

import { loadFixture } from '../../playwright/paths';
import { test } from '../../playwright/test';

test.describe('gRPC interactions', () => {

  test.slow(process.platform === 'darwin' || process.platform === 'win32', 'Slow app start on these platforms');
  let statusTag: Locator;
  let responseBody: Locator;
  let streamMessage: Locator;

  test.beforeEach(async ({ app, page }) => {
    const text = await loadFixture('grpc.yaml');
    await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);

    await page.getByLabel('Import').click();
    await page.locator('[data-test-id="import-from-clipboard"]').click();
    await page.getByRole('button', { name: 'Scan' }).click();
    await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
    await page.getByLabel('PreRelease gRPC').click();

    statusTag = page.locator('[data-testid="response-status-tag"]:visible');
    responseBody = page.locator('[data-testid="response-pane"] >> [data-testid="CodeEditor"]:visible', {
      has: page.locator('.CodeMirror-activeline'),
    });
    streamMessage = page.locator('[data-testid="request-pane"] button:has-text("Stream")');
  });

  test('can send unidirectional requests', async ({ page }) => {
    await page.getByLabel('Request Collection').getByTestId('Unary').click();
    await page.locator('[data-testid="request-pane"] >> text=Unary').click();
    await page.click('text=Send');

    // Check for the single Unary response
    await page.click('text=Response 1');
    await expect(statusTag).toContainText('0 OK');
    await expect(responseBody).toContainText('Berkshire Valley Management Area Trail');
  });

  test('can send bidirectional requests', async ({ page }) => {
    await page.getByLabel('Request Collection').getByTestId('Bidirectional Stream').press('Enter');
    await page.locator('text=Bi-directional Streaming').click();
    await page.click('text=Start');

    // Stream 3 client messages
    await streamMessage.click();
    await streamMessage.click();
    await streamMessage.click();

    // Check for the 3rd stream and response
    await page.locator('text=Stream 3').click();
    await page.locator('text=Response 3').click();

    // Finish the stream
    await page.locator('text=Commit').click();
    await expect(statusTag).toContainText('0 OK');
  });

  test('can send client stream requests', async ({ page }) => {
    await page.getByLabel('Request Collection').getByTestId('Client Stream').press('Enter');
    await page.click('text=Client Streaming');
    await page.click('text=Start');

    // Stream 3 client messages
    await streamMessage.click();
    await streamMessage.click();
    await streamMessage.click();

    // Finish the stream and check response
    await page.locator('text=Commit').click();
    await page.locator('text=Stream 3').click();
    await page.locator('text=Response 1').click();
    await expect(statusTag).toContainText('0 OK');
    await expect(responseBody).toContainText('point_count": 3');
  });

  test('can send server stream requests', async ({ page }) => {
    await page.getByLabel('Request Collection').getByTestId('Server Stream').press('Enter');
    await page.click('text=Server Streaming');
    await page.click('text=Start');

    // Check response
    await expect(statusTag).toContainText('0 OK');
    await page.locator('text=Response 64').click();
    await expect(responseBody).toContainText('3 Hasta Way');
  });

});