@connectrpc/connect-playwright
Advanced tools
Comparing version 0.3.2 to 0.4.0
import type { BrowserContext } from "@playwright/test"; | ||
import type { MethodImpl, ServiceImpl } from "@connectrpc/connect"; | ||
import type { MethodInfo, ServiceType, BinaryReadOptions, BinaryWriteOptions, JsonReadOptions, JsonWriteOptions } from "@bufbuild/protobuf"; | ||
import type { BinaryReadOptions, BinaryWriteOptions, DescMethod, DescService, JsonReadOptions, JsonWriteOptions } from "@bufbuild/protobuf"; | ||
export interface MockRouter { | ||
service: <S extends ServiceType>(service: S, handler: "mock" | Partial<ServiceImpl<S>>) => Promise<this>; | ||
rpc<M extends MethodInfo>(service: ServiceType, method: M, impl: "mock" | MethodImpl<M>): Promise<this>; | ||
service: <S extends DescService>(service: S, handler: "mock" | Partial<ServiceImpl<S>>) => Promise<this>; | ||
rpc<M extends DescMethod>(method: M, impl: "mock" | MethodImpl<M>): Promise<this>; | ||
} | ||
@@ -8,0 +8,0 @@ interface Options { |
@@ -16,5 +16,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createMockRouter = void 0; | ||
exports.createMockRouter = createMockRouter; | ||
const connect_1 = require("@connectrpc/connect"); | ||
const protobuf_1 = require("@bufbuild/protobuf"); | ||
const protocol_1 = require("@connectrpc/connect/protocol"); | ||
@@ -36,10 +35,10 @@ // Builds a regular expression for matching paths by appending the suffix onto | ||
}; | ||
function addMethodRoute(service, method, handler) { | ||
if (method.kind !== protobuf_1.MethodKind.Unary) { | ||
function addMethodRoute(method, handler) { | ||
if (method.methodKind !== "unary") { | ||
throw new Error("Cannot add non-unary method."); | ||
} | ||
const pathRegex = buildPathRegex(baseUrl, `/${service.typeName}/${method.name}`); | ||
const pathRegex = buildPathRegex(baseUrl, `/${method.parent.typeName}/${method.name}`); | ||
return context.route(pathRegex, async (route, request) => { | ||
if (handler !== "mock") { | ||
const router = (0, connect_1.createConnectRouter)(routerOptions).rpc(service, method, handler); | ||
const router = (0, connect_1.createConnectRouter)(routerOptions).rpc(method, handler); | ||
const routeHandler = router.handlers[0]; | ||
@@ -52,3 +51,3 @@ return universalHandlerToRouteResponse({ | ||
} | ||
const router = (0, connect_1.createConnectRouter)(routerOptions).rpc(service, method, (() => ({}))); | ||
const router = (0, connect_1.createConnectRouter)(routerOptions).rpc(method, (() => ({}))); | ||
const routeHandler = router.handlers[0]; | ||
@@ -67,7 +66,7 @@ return universalHandlerToRouteResponse({ | ||
return Promise.all(Object.entries(handler).map(([methodName, methodHandler]) => { | ||
const method = service.methods[methodName]; | ||
const method = service.method[methodName]; | ||
if (methodHandler === undefined) { | ||
throw new Error(`No method handler found for ${methodName}`); | ||
} | ||
return addMethodRoute(service, method, methodHandler); | ||
return addMethodRoute(method, methodHandler); | ||
})); | ||
@@ -83,8 +82,8 @@ } | ||
// Automatically pass-through all non-unary methods | ||
if (associatedMethod.kind !== protobuf_1.MethodKind.Unary) { | ||
if (associatedMethod.methodKind !== "unary") { | ||
return route.continue(); | ||
} | ||
const router = (0, connect_1.createConnectRouter)(routerOptions).rpc(service, associatedMethod, | ||
const router = (0, connect_1.createConnectRouter)(routerOptions).rpc(associatedMethod, | ||
// By returning an empty object, the response will be a default-constructed mock object. | ||
() => ({})); | ||
(() => ({}))); | ||
const routeHandler = router.handlers[0]; | ||
@@ -101,4 +100,4 @@ return universalHandlerToRouteResponse({ | ||
}, | ||
rpc: async (service, method, handler) => { | ||
await addMethodRoute(service, method, handler); | ||
rpc: async (method, handler) => { | ||
await addMethodRoute(method, handler); | ||
return Promise.resolve(mock); | ||
@@ -109,3 +108,2 @@ }, | ||
} | ||
exports.createMockRouter = createMockRouter; | ||
async function universalHandlerToRouteResponse({ route, routeHandler, request, }) { | ||
@@ -112,0 +110,0 @@ var _a; |
@@ -19,3 +19,3 @@ "use strict"; | ||
var g = generator.apply(thisArg, _arguments || []), i, q = []; | ||
return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; | ||
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; | ||
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } | ||
@@ -32,26 +32,3 @@ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } | ||
const test_1 = require("@playwright/test"); | ||
const protobuf_1 = require("@bufbuild/protobuf"); | ||
const TestService = { | ||
typeName: "test.v1.TestService", | ||
methods: { | ||
unaryOne: { | ||
name: "UnaryOne", | ||
I: protobuf_1.Int32Value, | ||
O: protobuf_1.StringValue, | ||
kind: protobuf_1.MethodKind.Unary, | ||
}, | ||
unaryTwo: { | ||
name: "UnaryTwo", | ||
I: protobuf_1.Int32Value, | ||
O: protobuf_1.StringValue, | ||
kind: protobuf_1.MethodKind.Unary, | ||
}, | ||
serverStreaming: { | ||
name: "ServerStreaming", | ||
I: protobuf_1.Int32Value, | ||
O: protobuf_1.StringValue, | ||
kind: protobuf_1.MethodKind.ServerStreaming, | ||
}, | ||
}, | ||
}; | ||
const test_pb_js_1 = require("./testdata/gen/test_pb.js"); | ||
// eslint-disable-next-line @typescript-eslint/require-await | ||
@@ -76,3 +53,3 @@ function mockFn() { | ||
it("works as intended", async () => { | ||
await mock.service(TestService, { | ||
await mock.service(test_pb_js_1.TestService, { | ||
unaryOne: () => { | ||
@@ -84,3 +61,3 @@ return { | ||
}); | ||
await mock.service(TestService, { | ||
await mock.service(test_pb_js_1.TestService, { | ||
unaryTwo: () => { | ||
@@ -94,3 +71,3 @@ return { | ||
it("allows await chaining", async () => { | ||
await (await mock.service(TestService, { | ||
await (await mock.service(test_pb_js_1.TestService, { | ||
unaryOne: () => { | ||
@@ -101,3 +78,3 @@ return { | ||
}, | ||
})).service(TestService, { | ||
})).service(test_pb_js_1.TestService, { | ||
unaryTwo: () => { | ||
@@ -112,3 +89,3 @@ return { | ||
void mock | ||
.service(TestService, { | ||
.service(test_pb_js_1.TestService, { | ||
unaryOne: () => { | ||
@@ -121,3 +98,3 @@ return { | ||
.then((handler) => { | ||
void handler.service(TestService, { | ||
void handler.service(test_pb_js_1.TestService, { | ||
unaryTwo: () => { | ||
@@ -133,3 +110,3 @@ return { | ||
try { | ||
await mock.service(TestService, { | ||
await mock.service(test_pb_js_1.TestService, { | ||
serverStreaming: mockFn, | ||
@@ -136,0 +113,0 @@ }); |
import type { BrowserContext } from "@playwright/test"; | ||
import type { MethodImpl, ServiceImpl } from "@connectrpc/connect"; | ||
import type { MethodInfo, ServiceType, BinaryReadOptions, BinaryWriteOptions, JsonReadOptions, JsonWriteOptions } from "@bufbuild/protobuf"; | ||
import type { BinaryReadOptions, BinaryWriteOptions, DescMethod, DescService, JsonReadOptions, JsonWriteOptions } from "@bufbuild/protobuf"; | ||
export interface MockRouter { | ||
service: <S extends ServiceType>(service: S, handler: "mock" | Partial<ServiceImpl<S>>) => Promise<this>; | ||
rpc<M extends MethodInfo>(service: ServiceType, method: M, impl: "mock" | MethodImpl<M>): Promise<this>; | ||
service: <S extends DescService>(service: S, handler: "mock" | Partial<ServiceImpl<S>>) => Promise<this>; | ||
rpc<M extends DescMethod>(method: M, impl: "mock" | MethodImpl<M>): Promise<this>; | ||
} | ||
@@ -8,0 +8,0 @@ interface Options { |
@@ -15,3 +15,2 @@ // Copyright 2023-2024 The Connect Authors | ||
import { createConnectRouter } from "@connectrpc/connect"; | ||
import { MethodKind } from "@bufbuild/protobuf"; | ||
import { readAllBytes, createAsyncIterable, } from "@connectrpc/connect/protocol"; | ||
@@ -33,10 +32,10 @@ // Builds a regular expression for matching paths by appending the suffix onto | ||
}; | ||
function addMethodRoute(service, method, handler) { | ||
if (method.kind !== MethodKind.Unary) { | ||
function addMethodRoute(method, handler) { | ||
if (method.methodKind !== "unary") { | ||
throw new Error("Cannot add non-unary method."); | ||
} | ||
const pathRegex = buildPathRegex(baseUrl, `/${service.typeName}/${method.name}`); | ||
const pathRegex = buildPathRegex(baseUrl, `/${method.parent.typeName}/${method.name}`); | ||
return context.route(pathRegex, async (route, request) => { | ||
if (handler !== "mock") { | ||
const router = createConnectRouter(routerOptions).rpc(service, method, handler); | ||
const router = createConnectRouter(routerOptions).rpc(method, handler); | ||
const routeHandler = router.handlers[0]; | ||
@@ -49,3 +48,3 @@ return universalHandlerToRouteResponse({ | ||
} | ||
const router = createConnectRouter(routerOptions).rpc(service, method, (() => ({}))); | ||
const router = createConnectRouter(routerOptions).rpc(method, (() => ({}))); | ||
const routeHandler = router.handlers[0]; | ||
@@ -64,7 +63,7 @@ return universalHandlerToRouteResponse({ | ||
return Promise.all(Object.entries(handler).map(([methodName, methodHandler]) => { | ||
const method = service.methods[methodName]; | ||
const method = service.method[methodName]; | ||
if (methodHandler === undefined) { | ||
throw new Error(`No method handler found for ${methodName}`); | ||
} | ||
return addMethodRoute(service, method, methodHandler); | ||
return addMethodRoute(method, methodHandler); | ||
})); | ||
@@ -80,8 +79,8 @@ } | ||
// Automatically pass-through all non-unary methods | ||
if (associatedMethod.kind !== MethodKind.Unary) { | ||
if (associatedMethod.methodKind !== "unary") { | ||
return route.continue(); | ||
} | ||
const router = createConnectRouter(routerOptions).rpc(service, associatedMethod, | ||
const router = createConnectRouter(routerOptions).rpc(associatedMethod, | ||
// By returning an empty object, the response will be a default-constructed mock object. | ||
() => ({})); | ||
(() => ({}))); | ||
const routeHandler = router.handlers[0]; | ||
@@ -98,4 +97,4 @@ return universalHandlerToRouteResponse({ | ||
}, | ||
rpc: async (service, method, handler) => { | ||
await addMethodRoute(service, method, handler); | ||
rpc: async (method, handler) => { | ||
await addMethodRoute(method, handler); | ||
return Promise.resolve(mock); | ||
@@ -102,0 +101,0 @@ }, |
@@ -18,3 +18,3 @@ // Copyright 2023-2024 The Connect Authors | ||
var g = generator.apply(thisArg, _arguments || []), i, q = []; | ||
return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; | ||
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; | ||
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } | ||
@@ -30,26 +30,3 @@ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } | ||
import { chromium } from "@playwright/test"; | ||
import { MethodKind, Int32Value, StringValue } from "@bufbuild/protobuf"; | ||
const TestService = { | ||
typeName: "test.v1.TestService", | ||
methods: { | ||
unaryOne: { | ||
name: "UnaryOne", | ||
I: Int32Value, | ||
O: StringValue, | ||
kind: MethodKind.Unary, | ||
}, | ||
unaryTwo: { | ||
name: "UnaryTwo", | ||
I: Int32Value, | ||
O: StringValue, | ||
kind: MethodKind.Unary, | ||
}, | ||
serverStreaming: { | ||
name: "ServerStreaming", | ||
I: Int32Value, | ||
O: StringValue, | ||
kind: MethodKind.ServerStreaming, | ||
}, | ||
}, | ||
}; | ||
import { TestService } from "./testdata/gen/test_pb.js"; | ||
// eslint-disable-next-line @typescript-eslint/require-await | ||
@@ -56,0 +33,0 @@ function mockFn() { |
{ | ||
"name": "@connectrpc/connect-playwright", | ||
"version": "0.3.2", | ||
"version": "0.4.0", | ||
"license": "Apache-2.0", | ||
@@ -14,2 +14,3 @@ "description": "e2e utilities for use with Playwright and Connect", | ||
"test": "playwright install chromium && jasmine --config=jasmine.json", | ||
"generate": "buf generate", | ||
"build": "npm run build:cjs && npm run build:esm", | ||
@@ -34,9 +35,10 @@ "build:cjs": "tsc --project tsconfig.json --module commonjs --outDir ./dist/cjs --declaration --declarationDir ./dist/cjs && echo >./dist/cjs/package.json '{\"type\":\"commonjs\"}'", | ||
"peerDependencies": { | ||
"@connectrpc/connect": "^1.3.0", | ||
"@connectrpc/connect": "^2.0.0-alpha.1", | ||
"@playwright/test": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"@arethetypeswrong/cli": "^0.13.5", | ||
"@playwright/test": "^1.40.1", | ||
"@types/node": "^20.10.6" | ||
"@bufbuild/buf": "^1.42.0", | ||
"@arethetypeswrong/cli": "^0.15.3", | ||
"@playwright/test": "^1.46.1", | ||
"@types/node": "^22.5.1" | ||
}, | ||
@@ -43,0 +45,0 @@ "files": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37168
20
720
4