ijpiantanida / talkback Goto Github PK
View Code? Open in Web Editor NEWA simple HTTP proxy that records and playbacks requests
License: MIT License
A simple HTTP proxy that records and playbacks requests
License: MIT License
Hello,
I couldn't find in docs anything related to multiple hosts. My ideal would be to have ability to provide options as array. Like this:
const opts = {
host: ['http://example.com', 'http://example2.com'],
record: talkback.Options.RecordMode.NEW,
port: 5544,
path: "./offline-tapes"
};
Is this already possible or is it something I need to introduce to the project via PR?
Thanks for the new feature! I've been using it for a few days now; one thing I noticed was that the README didn't have an example for providing a function instead of a string - might be useful for an uninitiated user.
Can we make it possible to use https instead of http. Perhaps with options: https, key and cert?
Greetings
Christian
Hello,
First of all, thanks for the great tool, fast to onboard.
I experience a problem of matching. I have some user session cookies in headers of my requests. I would like to ignore them (and maybe other stuffs in headers, like dates), because I can't reuse the recorded requests.
I use talkback to mock my API for development or load test. Not to test the features. So the session cookies are not usefull.
Is it possible to add a headerMatcher ?
Regards
Hi, what is the difference between the two npm modules?
https://www.npmjs.com/package/talkback
https://www.npmjs.com/package/ng-talkback
Both point to the same repo, here, but ng-talkback has no information on npm.
I was expecting ng-talkback to have some relation to Angular, but I don't see any.
What am I missing?
I'd like to record the actual request latency in the metadata. I cannot seem to persist any changes to meta
in a responseDecorator
. Is this intended?
Hello!
I discovered Talkback yesterday and really dig the simplicity of its API and that the tape format is easily human readable. I'm working on adding new testing infrastructure to an existing large system, and see this as a valuable tool to transparently sit between components and record activity between them for later analysis and playback (via another tool, as I don't think Talkback supports arbitrary tape replay right now)
However, Talkback's behavior of replaying tapes matching an incoming request subverts this use-case. Consider the following hypothetical request sequence:
GET /comment
: Get all commentsPOST /comment
: Create a new commentGET /foo
: Get all comments again, this time with the newly created oneIn this use-case, we expect the second GET
call to return a different response from the first, but Talkback will only record the first GET
request in this sequence and replay it for the second. This is problematic when situating Talkback as a transparent middle-man between two existing system components.
So, I propose an option that allows the "always replay" behavior to be disabled, and thereby enabling this use-case.
Also, I admit that it's entirely possible that there exists a better tool for this use-case and that it doesn't make sense to include this behavior in Talkback. I'm definitely open to alternatives, but my searching around the ecosystem kept leading me back here. If anyone knows of such a better tool, please let me know! 😁
My app sets a non-deterministic request id which the response has to match so I need to update the tape to include the request id.
Can we add a new option that allows the outbound tape response to be edited bodyUpdater
.
const opts = {
host: "http://localhost:9001",
port: 9000,
bodyMatcher: (tape, req) => { /** stripe out request id */},
bodyUpdater: (tape, req) => { /** get new request id from req and replace old request id instances from the tape */}
}
On my dev environment, I'm using openshift with a self-signed certificate (https), when trying to use this tool I get the following error: "reason: self signed certificate in certificate chain"
Is there a way to allow self-signed certificates?
{ url: '/api/auth/info',
headers:
{ 'x-forwarded-host': 'localhost:3000',
'x-forwarded-proto': 'http',
'x-forwarded-port': '3000',
'x-forwarded-for': '127.0.0.1',
cookie:
'_ga=GA1.1.1514412781.1557421740; Webstorm-a9376004=b9c98f11-f6b4-4bb3-84c3-0983d04fd04e; _gid=GA1.1.1489284077.1565034839',
'accept-language': 'en,en-US;q=0.9,es-419;q=0.8,es;q=0.7',
'accept-encoding': 'gzip, deflate, br',
referer: 'http://localhost:3000/',
'content-type': 'application/json;charset=utf-8',
'user-agent':
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
'x-auth-type-kiali-ui': '1',
accept: 'application/json, text/plain, */*',
connection: 'close',
host: 'localhost:3030' } }
Making real request to https://kiali-istio-system.127.0.0.1.nip.io/api/auth/info
Error handling request { FetchError: request to https://kiali-istio-system.127.0.0.1.nip.io/api/auth/info failed, reason: self signed certificate in certificate chain
at ClientRequest.<anonymous> (/home/josejulio/Documentos/redhat/kiali/kiali-mock-server/node_modules/node-fetch/lib/index.js:1455:11)
at ClientRequest.emit (events.js:182:13)
at TLSSocket.socketErrorListener (_http_client.js:392:9)
at TLSSocket.emit (events.js:182:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
message:
'request to https://kiali-istio-system.127.0.0.1.nip.io/api/auth/info failed, reason: self signed certificate in certificate chain',
type: 'system',
errno: 'SELF_SIGNED_CERT_IN_CHAIN',
code: 'SELF_SIGNED_CERT_IN_CHAIN' }
We have urls that are created from previous server responses like:
http://localhost:8081/payments/${paymentId}/transactions/${transactionId}/import
where http://localhost:8080
is the host key in the options object and /${paymentId}/transactions/${transactionId}/import is the url key in the recorded tapes.
As far as I understand, Talkback uses the url key when matching tapes. This will force a new call to the real server for every new variable value.
A solution is to introduce a url/pathname matcher property, where one could replace the variables with fixed values. I guess its much the same solution as you did with the bodyMatcher.
Any way to use this to record an replay for websocket interactions?
Given following:
var talkback = require("talkback");
var server = talkback({
host: "https://jsonplaceholder.typicode.com",
path: __dirname + "/tapes",
port: 3002,
debug: true
});
server.start();
I am getting response 500, when requesting localhost:3002/todos/1
with header: Content-Type: application/json
.
Removing this method fixes the problem.
I don't understand why this is necessary.
Hi Guys,
I would appreciate to know whats the logic behind encoded body parts of the request?
What I usually get as a recorded tape something like this;
req: {
headers: {},
url: "/graphql",
method: "POST",
body: "ewogICJxdWVyeSI6ICJcblx0XHRcdFx0cXVlcnk.......",
},
I hope you agree that any test setup rather likes it to be readable and understandable and it is the usual case that you use talkbak in development. For that reason it would be nice to know whats the philosophy behind encoding and how I can disable that.
I tried to understand the logic inside the talkback, but I am sure at least the author can say in one shot what is the reasonable way to approach that.
Here is what I found in the talkback source
// export const jsonTypes = [
// equals("application/json"),
// equals("application/x-amz-json-1.0"),
// equals("application/x-amz-json-1.1"),
// (contentType: string) => contentType.startsWith("application/") && contentType.endsWith("+json"),
// ];
// const humanReadableContentTypes = [
// equals("application/javascript"),
// equals("text/css"),
// equals("text/html"),
// equals("text/javascript"),
// equals("text/plain"),
// ...jsonTypes,
// ];
// some logic in talkback expecting content-encoding is not set or it has the value "identity"
// so I should make sure in my FE code that I have a header like this one:
// request headers { headers: { "content-encoding": "identity" } }
The docu is not really mentioning it either.
Thanks a lot in advance, and many thanks for creating talkback its a rocket for me in any project.
Regards...
Your proposal on how to handle partial body matching might also cover this issue. As one could maybe supply a deep match or body sorting function.
During some readability refactoring I wanted to sort some lines of code alphabetically, but because these were setting values for a request payload, it caused a cache miss in Talkback.
What I assume is the issue here is the payload object is unsorted when stringified. Which probably is in everyones interest for most situations in a performance perspective. But here it causes a cache miss for equal data with different ordering.
Working around the issue is no worse than rebuilding the Talkback request-response pair, but it may be tedious for bigger rounds of refactoring.
A configuration flag for choosing to sort the body by key names. Opting for a flag as It will undoubtedly be a performance hit.
Flag Name | Value | Description | Default |
---|---|---|---|
sortRequestBody | Boolean |
Whether or not to sort the request body before building a cache. This removes the need for specific ordering in request payloads. | false |
When running our tests we are starting 10 talkback servers, one for each of the different services our app is accessing. When the test runner terminates, all talkback servers reports their individual exit summary.
It would have been nice to distinguish the different exit summaries.
What if a talkback server can be given a name
in its options, which them can be printed in the SUMMARY heading if present?
Example:
===== SUMMARY Customer server =====
Unused tapes:
- GET_customers_by_customerNumber.json5
- PUT_change_telephoneNumber_for_newly_made_customer.json5
===== SUMMARY Messaging server =====
===== SUMMARY Sales server =====
===== SUMMARY Order server =====
Unused tapes:
- UseCase-1_13_pay.json5
- UseCase-1_14_issue-tickets.json5
- UseCase-1_15_order-overview.json5
And for people that'd made a lib from scratch (not Talkback obviously), https://github.com/servirtium/README/blob/master/starting-a-new-implementation.md
Hi nice work with this module.
The console messages like https://github.com/ijpiantanida/talkback/blob/master/src/tape-store.js#L42 don't play well with some test reporters I would like to have the option to disable those, could it be a configurable flag (verbose
/debug
) like summary
? Or maybe use the debug
module?
Hi,
I'm trying to mock a response with multiple "Set-Cookies" header. As I saw, only the last 'Set-Cookies' entry in the file gets sent in the response. So instead of e.g. 5 Set-Cookies header, I get only one. Can this be a bug, or do I need to address this in some special way in the json5 file?
Thanks,
Sandor
Hi @ijpiantanida,
many thanks for you this fantastic library, I used it in several projects. It is the core of my new testing philosophy that prefers integrative testing.
One problem I always have though:
The headers as part of the key inside the request always differ and consume time to figure out.
In the most cases I end up excluding almost all headers at the end, one by one. Specifically on CI environments a list of complete new headers additionally comes up, so it needs one more config with some dev ops guy.
So how about introducing a list of NOT ignored headers (e.g. considerOnlyHeaders) , basically the negation of the ignoreHeaders list. All other headers will be ignored?
By having that you would reduce the last complexity by setting up a new project with that and make it more transparent what is the actual comparison key for each tape. This can be an extra config not touching all the previous users with this feature.
So what do you think, would that make sense?
I guess it should be in dependencies, coz its in the resulting bundle (dist/index.js
). Am I right or I missed smth?
I start multiple Talkback servers in the same Node script, each handling the requests to a specific backend server.
The code looks something like this:
const startTalkbackServer = (serverName: string) => {
const options = {
name: serverName,
host: config.get<string>(`${serverName}.talkbackUrl`),
port: config.get<string>(`${serverName}.talkbackPort`),
path: `./talkback/cached_responses/${serverName}`,
// ...
};
const server = talkback(options);
server.start(() => {
console.log(`Talkback server started on http://localhost:${options.port} for ${options.host} with tapes at ${options.path}`);
});
};
['accounts', 'customers'].forEach(startTalkbackServer);
This works very well. The only issue we have with this, is that the log output from each of the servers does not reflect the server name provided in the options. The log output from both servers have the same name in the log line. This is always the name of the last server started.
For example when the the summary is being printed from these two servers, it looks like this:
[talkback] 2022-06-23T07:55:49.200Z [customers] [INFO] ===== SUMMARY =====
...
[talkback] 2022-06-23T07:55:49.300Z [customers] [INFO] ===== SUMMARY =====
...
Any idea why this is happening?
For example having the following setup and tapes:
index.js
const talkback = require("talkback");
const opts = {
host: "https://example.com",
};
const server = talkback(opts);
server.start(() => console.log("Talkback Started"));
tapes/quotes.json5
{
meta: {
createdAt: '2019-03-19T22:03:41.814Z',
host: 'https://example.com',
resHumanReadable: true,
},
req: {
url: '/test.json',
method: 'GET',
headers: {
accept: '*/*',
'user-agent': 'curl',
},
body: '',
},
res: {
status: 200,
headers: {
'content-type': [
'application/json; charset=UTF-8',
],
date: [
'Tue, 19 Mar 2019 22:03:42 GMT',
],
expires: [
'Tue, 26 Mar 2019 22:03:42 GMT',
],
'last-modified': [
'Tue, 19 Mar 2019 22:00:27 GMT',
],
'content-length': [
'46',
],
connection: [
'close',
],
},
body: {
words: 'in special “quotes” break',
},
},
}
node index.js
curl -v -H 'User-Agent: curl' http://localhost:8080/test.json
Returns
* Excess found in a non pipelined read: excess = 4, size = 42, maxdownload = 42, bytecount = 0
{
"words": "in special “quotes” brea
tapes/emojis.json5
{
meta: {
createdAt: '2019-03-19T22:03:41.814Z',
host: 'https://example.com',
resHumanReadable: true,
},
req: {
url: '/test2.json',
method: 'GET',
headers: {
accept: '*/*',
'user-agent': 'curl',
},
body: '',
},
res: {
status: 200,
headers: {
'content-type': [
'application/json; charset=UTF-8',
],
date: [
'Tue, 19 Mar 2019 22:03:42 GMT',
],
expires: [
'Tue, 26 Mar 2019 22:03:42 GMT',
],
'last-modified': [
'Tue, 19 Mar 2019 22:00:27 GMT',
],
'content-length': [
'33',
],
connection: [
'close',
],
},
body: {
emojis: 'also 😢 break',
},
},
}
curl -v -H 'User-Agent: curl' http://localhost:8080/test2.json
Returns
* Excess found in a non pipelined read: excess = 2, size = 31, maxdownload = 31, bytecount = 0
{
"emojis": "also 😢 break"
Notice how the response is malformed and missing the closing brackets and objects.
A workaround is to remove the response content-length
.
I've been using nock for a while and tried to migrate to your library.
Much better, easier, great job!
They only issue we have is that our scraping axios client is randomising headers (user agent, etc) on each request. Thus the requests never get matched. Ignore headers is not an option, because there are over 20 headers that may or may not be randomised. Is it possible to provide header matcher function or disabled header matching all-together.
FYI https://github.com/nock/nock#enable_reqheaders_recording-option
Nock does not bother matching the recordings by headers by default, because it brings a lot of similar issues....
I have used VCR gem in ruby before and it makes it seemless by creating one tape for each test which can be pointed to after the recording is done. It also goes down the requests in the order it receives during recording. It might be more opinionated, but it makes for a more repeatable integration test.
I am using selenium-webdriver with talkback to record the requests and playback in DISABLED mode to repeat application behavior. The issue is that if the same requests are being made with different responses, only the first one recorded is played back. In my scenario, I have an empty body response in the first response, and then a non-empty response after an action is taken on the webpage. I can certainly deleted the earlier tape with the empty response, but that wouldn't reflect realistic integration testing which talkback intends to solve.
An example I would like to use is adding to cart functionality. I would like to take the user through adding a product to cart by adding something from the page. At the first the cart is empty which means the response was empty, and then the user adds something to the cart which means the response is filled with a product object. This wouldn't precisely reflect the order of actions by the user in talkback.
It's possible I maybe overlooking something here. I look forward to your response.
Hello there 👋
First of all thanks for the effort you have put into this project. We have been using it to mock our API, and its flexibility is key.
I have a bug to report tho, and I believe I found the culprit.
The issue is that it isn't saving the tapes in human-readable form, which makes it a bit harder to debug them.
The issue is related to the case sensitivity of the content-type
headers matcher (here) which I believe should be case insensitive.
For instance, our SDK uses the following request to communicate with the API:
return api
.request(`checkouts/${checkoutId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formattedPayload),
});
And that causes the tapes to be recorded like:
body: 'ewogICJwYXltZW50X3R5cGUiOiAiYmFu...(content)',
Make a request using the following content type format:
const talkbackURL = "http://localhost:3030"
fetch(talkbackURL, {
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({"foo": "bar"}),
}).then(console.log)
Check the generated tape
{"foo": "bar"}
When checking human-readable content type, ignore the case
// https://github.dev/ijpiantanida/talkback/blob/main/src/utils/headers.ts
static read(headers: any, headerName: string) {
const caseInsensitiveKey = Object.key(headers)
.find(h => h.toLowerCase() === headerName.toLowerCase())
const value = headers[caseInsensitiveKey];
if (Array.isArray(value)) {
return value[0];
} else {
return value;
}
}```
The new RecordMode
is great! I especially like the ability to specify it per-request.
An additional use case for the new RecordMode
would be an ALWAYS
mode. In other words, a new tape is created with a request and response, whether or not a matching tape exists.
An example where this could be useful is this:
GET /serviceB/info
, no headers, no body
If I use RecordMode.New
, the 404 will be returned forever, because the initial tape was made from the bad response, and then re-used
If I use RecordMode.Overwrite
, I lose the middle tape, which had the good 'info'
If I use RecordMode.Disabled
, I don't get a tape at all
With RecordMode.Always
, I'll get all three tapes - then I can keep the tape I like, change over to RecordMode.Disabled
, and re-run
Thoughts/opinions? I'd be happy to do a PR on this if you're interested and don't have time
Why do you delete host from headers? Can you make this optional?
Getting this error when trying to record a get request with no body
Error handing request SyntaxError: Unexpected end of JSON input
at JSON.parse
at Tape.normalizeBody
at new Tape
I think its from here? https://github.com/ijpiantanida/talkback/blob/master/src/tape.js#L69
JSON.parse
error when this.req.body
is undefined
I have a situation where I want to store human readable content but I cannot do that because my browser always send 'accept-encoding': 'gzip, deflate, br'
and it will be passed to backend server as well and my response body always end up base64 encoded.
I tried using chrome extension to remove 'accept-encoding
from headers. Server then returns plain text and talkback
also store response body in json. But this is not good when we work as a team. I think there should be a way to handle this kind of situation when we setting up talkback server.
Thanks for making talkback I really like it.
I could give the following a try and make a PR if you think the it sounds like a worthwhile undertaking, @ijpiantanida.
My team and I have often found that a request body contains some piece of ever-changing data, e.g. a date or timestamp. Consequently, Talkback is unable to serve a cached response for the request the next time we run our tests.
The new ignore body option partially solves our problem: It works fine when we want to cache just one response for a given URL. But there are some URLs for which we need to cache two or more responses and serve them based on differing characteristics of the bodies. (This is especially true for GraphQL-endpoints, where the body is the only thing that matters and we may have hundreds of different bodies.) Ignore body is not of much help to us in these situations.
We discussed this in my team. Our best idea was to giving Talkback-users the option of adding a reqBodyIsRegex
field to the meta
-object in the cached response file, signifying that the request body is to be interpreted as a regular expression (requiring the author to convert the string to a regex). If any request body matches the regex, the cached response is served, exactly as stored. (Regex capturing groups could be used to adapt responses in the future, but I think this should not be in the first version of this.)
{
meta: {
createdAt: "2018-02-16T14:51:35.972Z",
host: "http://example.com/",
resHumanReadable: true,
reqBodyIsRegex: true,
},
req: {
body: 'Your body as a regex here. \(You would probably have to escape parentheses and stuff, but exactly how, remains to be seen\)'
}
...
}
My thoughts are that exact matching will have priority over regex-matching. I do not have any ideas about how to tie-break between competing regexes, but my guess is there's either no solution or some really good, pre-existing solution.
Talkback keeps generating new cached responses after server restart even though the requests are identical. I thought the expected behaviour was that identical requests would cause the cached response to be returned.
I'm guessing differences in meta
and res
shouldn't cause a new cached response to be generated?
Hi,
first: thank you so much for this awesome project! It rocks.
I have a simple case.
I start talk back in CI than I run the tests, and now I need to stop it somehow.
I see localServer.stop() in the doc but, it implies that the script that is tarting the server is somehow informed from outside that tests are done running.
A separate node script just to call localServer.stop(), fails, since the server is not initialized in this context and its not a singleton as it looks like. What should I do?
Basically you always need it if you want your server and tests to run as one command and you dont want to deal with two terminals.
I think this is a very common situation and worth mentioning.
Thanks in advance.
Denis.
The use of a Location header seems unsupported in Talkback.
I have tried to use the responseDecorator
to alter the Location header that is stored in the tape, but since the response when no tape is found is from the real server, the client will follow that URL instead of requesting Talkback. This results in no tapes being stored for the requests that follows the Location header. In order for the client to request Talkback when receiving a Location header, Talkback would need to alter the Location header before responding to the client even when no tapes are found.
The solution seems trivial after looking at src/request-handler.js
, and I would be more than willing to create a PR for this functionality.
Hello,
I've started using Node v15.2.1
with talkback and discovered my simple requests are failing with it.
Here is the stack trace:
Error handling request TypeError: Cannot read property 'content-encoding' of undefined
at Function.Headers.read (/Users/halil/thanx/talkback/src/utils/headers.ts:2:434)
at ContentEncoding.contentEncoding (/Users/halil/thanx/talkback/src/utils/content-encoding.ts:2:7364)
at ContentEncoding.isUncompressed (/Users/halil/thanx/talkback/src/utils/content-encoding.ts:2:6802)
at Tape.normalizeBody (/Users/halil/thanx/talkback/src/tape.ts:3:2493)
at new Tape (/Users/halil/thanx/talkback/src/tape.ts:3:31)
at RequestHandler. (/Users/halil/thanx/talkback/src/request-handler.ts:2:10789)
at step (/Users/halil/thanx/talkback/src/request-handler.ts:2:8237)
at Object.next (/Users/halil/thanx/talkback/src/request-handler.ts:2:5187)
at /Users/halil/thanx/talkback/src/request-handler.ts:2:4300
at new Promise ()
at __awaiter (/Users/halil/thanx/talkback/src/request-handler.ts:2:3473)
at RequestHandler.handle (/Users/halil/thanx/talkback/src/request-handler.ts:2:10024)
at TalkbackServer. (/Users/halil/thanx/talkback/src/server.ts:3:95)
at step (/Users/halil/thanx/talkback/src/server.ts:2:8450)
at Object.next (/Users/halil/thanx/talkback/src/server.ts:2:5314)
at /Users/halil/thanx/talkback/src/server.ts:2:4406
at new Promise ()
at __awaiter (/Users/halil/thanx/talkback/src/server.ts:2:3561)
at IncomingMessage. (/Users/halil/thanx/talkback/src/server.ts:2:10702)
Here is my request in curl format:
curl --request GET \
--url http://localhost:3000/apps/crew \
--header 'Content-Type: application/json'
Also, 16 tests are failing in the talkback repository when I run them with Node 15.2.1.
I've experienced problems with requests not being served when their key order changes. I have a PR coming up which fixes this; just wanted to make the issue to have something to tag it onto.
My case: everytime I run as record-mode, I'm seeing res body as base64. I believe you should be able to enforce req and res as humanReadable at options, instead of changing stuff through decorators for meta data.
so by default the tapes get named unnamed-<number>.json5
if you have a few tapes and you haven't manually renamed them and you delete one from the middle. example:
unnamed-1.json5
unnamed-2.json5
(deleted tape because it became unused)
unnamed-4.json5
the default numbering will calculate that there are currently 3 tapes and the next tape should be saved at unnamed-4.json5
which will overwrite the previous tape.
Suggestion, switch to a different naming convention that is resilient to this...
I will submit a PR shortly, it will likely mean a breaking change to the signature of the tapeNameGenerator
function.
First off, thank you for the amazing work @ijpiantanida, picking up from where yakbak left off and expanding on it was no small venture, so thank you.
I'm having amazing success with talkback
. I'm integrating it into a stack that includes jest and puppeteer via jest-puppeteer.
Using jest
and puppeteer
I'm able to run my app in an actual browser, headlessly, and write jest tests against user flows to create a complete set of integration tests while having all the api requests proxy through talkback
. This is in an early stage, but looks incredibly promising.
puppeteer
provides the ability to intercept http requests.
If talkback
exposed some of the lower level apis like RequestHandler
and OptionsFactory
this could open up some incredible possibilities.
Using puppeteer
's intercept functionality in conjunction with talkback
s tape recording functionality exposed via new apis without the need to create a whole new server could be extremely powerful.
Imagine it, having completely encapsulated full feature user flow integration tests run in a single node process. This aligns very strongly with your testing requirements from your great blog post.
As you can tell I'm super excited about these ideas and tooling possibilities.
In summary, again THANK YOU for your amazing work, and please let me know your thoughts/concerns. I'd love to explore making PRs where I can if this is something you're interested in.
Was additionally thinking talkback
could expose a "middleware", which could help users who may already have a server, but still want to benefit from talkback
's functionality without needing to make a whole new server?
const talkbackMiddleware = new talkback.middleware(opts);
app.use('/api', talkbackMiddleware)
talkback.Options.RecordMode.NEW
talkback.Options.RecordMode.NEW
After 1. Talkback tries to load a tape, but there is no tape, so it creates one after sending the request to the original server. The response is a redirect to https://github.com.
After 2. Talkback loads existing tapes, and matches with tape created for 1. The request itself fails and no other tape will get created.
The root cause seems to be Talkback storing URL's path as URL in the tapes:
{
headers: { ... },
url: '/',
method: 'GET',
body: '',
}
And the TapeMatcher compares the url
part which are same in HTTPS and HTTP cases.
Hi,
Can we make it possible to allow self signed certificates from the host?
Also an option to start a https server instead of http could be good
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.