From 38c3678b4b3a65eef39d7cb3b6239567764e549f Mon Sep 17 00:00:00 2001 From: George He Date: Fri, 24 Nov 2023 18:12:58 +0800 Subject: [PATCH 1/2] test: add tests for grpc operations --- .../fixtures/route_guide.bin | Bin 864 -> 1332 bytes packages/insomnia-smoke-test/server/grpc.ts | 12 ++ .../tests/smoke/grpc.test.ts | 119 +++++++++++++++--- .../__fixtures__/library/route_guide.proto | 9 ++ 4 files changed, 123 insertions(+), 17 deletions(-) diff --git a/packages/insomnia-smoke-test/fixtures/route_guide.bin b/packages/insomnia-smoke-test/fixtures/route_guide.bin index 489f4b3c5e8ba78eb4868b223a077f89ebd2d927..565ddaae337ae3becbc8058230dacdde28451ef3 100644 GIT binary patch delta 539 zcmaJ;Jxjwt81@oc>!~QQNQqQR77IcS>LLnK3Z;q&r3ivcxTM!JG|7d_#hO9-8^m9r zqnqgL=I&4MCpbEqTucQKxA);9gOC z{mz53*^{+QX_Y3MXT_1s;Xi8DpB7xk1GIz{M!y4ho2vFg`|< zhYqr=k$WX#P9n=fo@;Z=6Lhm(uj~K4|MBn*OpQALDiclHP)m`v3e_=5w$hkvFPpV0 xEL~zRF0?t=Q+7e?^+{LCpq=(x>N*#!aMIR`Kalsz4k>>~um08An7eJL?JtS+wVeO} delta 67 zcmdnO^?*%_>n5Z diff --git a/packages/insomnia-smoke-test/server/grpc.ts b/packages/insomnia-smoke-test/server/grpc.ts index 943d025ec69..9b0df85781a 100644 --- a/packages/insomnia-smoke-test/server/grpc.ts +++ b/packages/insomnia-smoke-test/server/grpc.ts @@ -59,6 +59,11 @@ const getFeature: HandleCall = (call: any, callback: any) => { callback(null, checkFeature(call.request)); }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const echoMetadata: HandleCall = (call: any, callback: any) => { + callback(null, { metadata: call.metadata.getMap() }); +}; + /** * listFeatures request handler. */ @@ -192,6 +197,12 @@ export const startGRPCServer = (port: number) => { const server = new grpc.Server(); // Enable reflection + // use this to generate .bin file: + // protoc \ + // --descriptor_set_out=packages/insomnia-smoke-test/fixtures/route_guide.bin \ + // --include_imports packages/insomnia/src/network/grpc/__fixtures__/library/route_guide.proto \ + // -I \ + // -I const descriptorSet = '../../packages/insomnia-smoke-test/fixtures/route_guide.bin'; addReflection(server, descriptorSet); @@ -201,6 +212,7 @@ export const startGRPCServer = (port: number) => { listFeatures: listFeatures, recordRoute: recordRoute, routeChat: routeChat, + echoMetadata, }); server.bindAsync(`localhost:${port}`, grpc.ServerCredentials.createInsecure(), error => { if (error) { diff --git a/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts b/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts index 326cae04820..719715e4b47 100644 --- a/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts +++ b/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts @@ -3,17 +3,51 @@ import { expect } from '@playwright/test'; import { loadFixture } from '../../playwright/paths'; import { test } from '../../playwright/test'; -test('can send gRPC requests with reflection', async ({ app, page }) => { - test.slow(process.platform === 'darwin' || process.platform === 'win32', 'Slow app start on these platforms'); - const statusTag = page.locator('[data-testid="response-status-tag"]:visible'); - const responseBody = page.locator('[data-testid="response-pane"] >> [data-testid="CodeEditor"]:visible', { - has: page.locator('.CodeMirror-activeline'), +test.describe('test grpc requests', async () => { + test('test unary request', async ({ app, page }) => { + test.slow(process.platform === 'darwin' || process.platform === 'win32', 'Slow app start on these platforms'); + + const statusTag = page.locator('[data-testid="response-status-tag"]:visible'); + const responseBody = page.locator('[data-testid="response-pane"] >> [data-testid="CodeEditor"]:visible', { + has: page.locator('.CodeMirror-activeline'), + }); + + await page.getByRole('button', { name: 'Create in project' }).click(); + + const text = await loadFixture('grpc.yaml'); + await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text); + + await page.getByRole('menuitemradio', { name: '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.getByText('CollectionPreRelease gRPCjust now').click(); + + // choose request + await page.getByLabel('Request Collection').getByTestId('UnaryWithOutProtoFile').press('Enter'); + await expect(page.getByRole('button', { name: 'Select Method' })).toBeDisabled(); + await page.getByTestId('button-server-reflection').click(); + + // choose method + await page.getByRole('button', { name: 'Select Method' }).click(); + await page.getByRole('menuitem', { name: 'RouteGuide/GetFeature' }).click(); + + // start + await page.getByRole('button', { name: 'Send' }).click(); + + // verify + await page.getByRole('tab', { name: 'Response 1' }).click(); + await expect(statusTag).toContainText('0 OK'); + await expect(responseBody).toContainText('Berkshire Valley Management Area Trail'); }); - await page.getByRole('button', { name: 'Create in project' }).click(); + test('test client side stream', async ({ app, page }) => { + test.slow(process.platform === 'darwin' || process.platform === 'win32', 'Slow app start on these platforms'); - const text = await loadFixture('grpc.yaml'); - await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text); + const statusTag = page.locator('[data-testid="response-status-tag"]:visible'); + const responseBody = page.locator('[data-testid="response-pane"] >> [data-testid="CodeEditor"]:visible', { + has: page.locator('.CodeMirror-activeline'), + }); await page.getByRole('menuitemradio', { name: 'Import' }).click(); await page.locator('[data-test-id="import-from-clipboard"]').click(); @@ -21,18 +55,69 @@ test('can send gRPC requests with reflection', async ({ app, page }) => { await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click(); await page.getByLabel('PreRelease gRPC').click(); - await page.getByLabel('Request Collection').getByTestId('UnaryWithOutProtoFile').press('Enter'); - await expect(page.getByRole('button', { name: 'Select Method' })).toBeDisabled(); - await page.getByTestId('button-server-reflection').click(); + // await page.getByRole('button', { name: 'Create in project' }).click(); + + const text = await loadFixture('grpc.yaml'); + await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text); await page.getByRole('button', { name: 'Select Method' }).click(); await page.getByRole('option', { name: 'RouteGuide/GetFeature' }).click(); - await page.getByRole('tab', { name: 'Unary' }).click(); - await page.getByRole('button', { name: 'Send' }).click(); + // await page.getByRole('menuitemradio', { name: '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.getByText('CollectionPreRelease gRPCjust now').click(); + + // choose request + await page.getByLabel('Request Collection').getByTestId('UnaryWithOutProtoFile').press('Enter'); + await expect(page.getByRole('button', { name: 'Select Method' })).toBeDisabled(); + await page.getByTestId('button-server-reflection').click(); + + // choose method + await page.getByRole('button', { name: 'Select Method' }).click(); + await page.getByRole('menuitem', { name: 'RouteGuide/RecordRoute' }).click(); + + // start + await page.getByRole('button', { name: 'Send' }).click(); + await page.getByRole('button', { name: 'Commit' }).click(); - // Check for the single Unary response - await page.getByRole('tab', { name: 'Response 1' }).click(); - await expect(statusTag).toContainText('0 OK'); - await expect(responseBody).toContainText('Berkshire Valley Management Area Trail'); + // verify + await page.getByRole('tab', { name: 'Response 1' }).click(); + await expect(statusTag).toContainText('0 OK'); + await expect(responseBody).toContainText('point_count": 0'); + }); + + test('test bidirectional stream', async ({ app, page }) => { + test.slow(process.platform === 'darwin' || process.platform === 'win32', 'Slow app start on these platforms'); + + const statusTag = page.locator('[data-testid="response-status-tag"]:visible'); + + await page.getByRole('button', { name: 'Create in project' }).click(); + + const text = await loadFixture('grpc.yaml'); + await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text); + + await page.getByRole('menuitemradio', { name: '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.getByText('CollectionPreRelease gRPCjust now').click(); + + // choose request + await page.getByLabel('Request Collection').getByTestId('UnaryWithOutProtoFile').press('Enter'); + await expect(page.getByRole('button', { name: 'Select Method' })).toBeDisabled(); + await page.getByTestId('button-server-reflection').click(); + + // choose method + await page.getByRole('button', { name: 'Select Method' }).click(); + await page.getByRole('menuitem', { name: 'RouteGuide/RouteChat' }).click(); + + // start + await page.getByRole('button', { name: 'Start' }).click(); + await page.getByRole('button', { name: 'Commit' }).click(); + + // verify + await expect(statusTag).toContainText('0 OK'); + }); }); diff --git a/packages/insomnia/src/network/grpc/__fixtures__/library/route_guide.proto b/packages/insomnia/src/network/grpc/__fixtures__/library/route_guide.proto index b519f558288..29a1ab65f81 100644 --- a/packages/insomnia/src/network/grpc/__fixtures__/library/route_guide.proto +++ b/packages/insomnia/src/network/grpc/__fixtures__/library/route_guide.proto @@ -21,6 +21,8 @@ option objc_class_prefix = "RTG"; package routeguide; +import "google/protobuf/empty.proto"; + // Interface exported by the server. service RouteGuide { // A simple RPC. @@ -50,6 +52,9 @@ service RouteGuide { // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} + + + rpc EchoMetadata(google.protobuf.Empty) returns (Metadata) {} } // Points are represented as latitude-longitude pairs in the E7 representation @@ -109,3 +114,7 @@ message RouteSummary { // The duration of the traversal in seconds. int32 elapsed_time = 4; } + +message Metadata { + map metadata = 1; +} From bb3d04f28fee1b633faafa7ca035793b3437136a Mon Sep 17 00:00:00 2001 From: George He Date: Mon, 29 Apr 2024 14:40:38 +0800 Subject: [PATCH 2/2] test: add 2 cases for bidirectional and client side streaming --- .../tests/smoke/grpc.test.ts | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts b/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts index 719715e4b47..cd854ddf91e 100644 --- a/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts +++ b/packages/insomnia-smoke-test/tests/smoke/grpc.test.ts @@ -21,7 +21,7 @@ test.describe('test grpc requests', async () => { 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.getByText('CollectionPreRelease gRPCjust now').click(); + await page.getByLabel('PreRelease gRPC').click(); // choose request await page.getByLabel('Request Collection').getByTestId('UnaryWithOutProtoFile').press('Enter'); @@ -30,7 +30,7 @@ test.describe('test grpc requests', async () => { // choose method await page.getByRole('button', { name: 'Select Method' }).click(); - await page.getByRole('menuitem', { name: 'RouteGuide/GetFeature' }).click(); + await page.getByLabel('/RouteGuide/GetFeature', { exact: true }).click(); // start await page.getByRole('button', { name: 'Send' }).click(); @@ -49,25 +49,16 @@ test.describe('test grpc requests', async () => { has: page.locator('.CodeMirror-activeline'), }); - await page.getByRole('menuitemradio', { name: '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(); - - // await page.getByRole('button', { name: 'Create in project' }).click(); + await page.getByRole('button', { name: 'Create in project' }).click(); + // import collection const text = await loadFixture('grpc.yaml'); await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text); - - await page.getByRole('button', { name: 'Select Method' }).click(); - await page.getByRole('option', { name: 'RouteGuide/GetFeature' }).click(); - - // await page.getByRole('menuitemradio', { name: '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.getByText('CollectionPreRelease gRPCjust now').click(); + await page.getByRole('menuitemradio', { name: '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(); // choose request await page.getByLabel('Request Collection').getByTestId('UnaryWithOutProtoFile').press('Enter'); @@ -76,7 +67,7 @@ test.describe('test grpc requests', async () => { // choose method await page.getByRole('button', { name: 'Select Method' }).click(); - await page.getByRole('menuitem', { name: 'RouteGuide/RecordRoute' }).click(); + await page.getByLabel('/RouteGuide/RecordRoute', { exact: true }).click(); // start await page.getByRole('button', { name: 'Send' }).click(); @@ -95,9 +86,9 @@ test.describe('test grpc requests', async () => { await page.getByRole('button', { name: 'Create in project' }).click(); + // import collection const text = await loadFixture('grpc.yaml'); await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text); - await page.getByRole('menuitemradio', { name: 'Import' }).click(); await page.locator('[data-test-id="import-from-clipboard"]').click(); await page.getByRole('button', { name: 'Scan' }).click(); @@ -111,7 +102,7 @@ test.describe('test grpc requests', async () => { // choose method await page.getByRole('button', { name: 'Select Method' }).click(); - await page.getByRole('menuitem', { name: 'RouteGuide/RouteChat' }).click(); + await page.getByLabel('/RouteGuide/RouteChat', { exact: true }).click(); // start await page.getByRole('button', { name: 'Start' }).click();