-
Notifications
You must be signed in to change notification settings - Fork 10
API Proxy for UI Tests #6927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Proxy for UI Tests #6927
Conversation
yarn install | ||
yarn codegen | ||
REACT_APP_ENVIRONMENT=pr-site-$PR_SITE_NUM yarn run build --aot --no-watch --no-progress | ||
REACT_APP_ENVIRONMENT=test yarn run build --aot --no-watch --no-progress |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we go with this approach, I will delete the unused PR site configuration files.
@@ -0,0 +1,19 @@ | |||
const matchReq = req => req.method === 'OPTIONS' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only handler that is hand-edited. All of the OPTIONS method responses were basically identical, so I consolidated them into one file.
@@ -0,0 +1,28 @@ | |||
import * as nu from 'util' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Start of non-generated code.
const create = (logStream = process.stderr) => { | ||
let lastStamp = -Infinity | ||
|
||
const truncate = ms => Math.floor(ms / 60e3) * 60e3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Codacy says this style of number can be inaccurate. However, (1) I disagree, (2) It wouldn't matter if they were, and (3) I think it is easier to see the value when not crowded with zeros.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree that codacy's rule doesn't make sense here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does .mjs
signify?
Please update the README with how to run this locally, in replay and record modes
const create = (logStream = process.stderr) => { | ||
let lastStamp = -Infinity | ||
|
||
const truncate = ms => Math.floor(ms / 60e3) * 60e3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree that codacy's rule doesn't make sense here
req.startTimeMs = Date.now() | ||
req.index = requestIndex++ | ||
res.index = req.index | ||
req.log = (...formatArgs) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean the ...formatArgs
part, which is just variadic arguments in JS (probably like ES2015+).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern is in in the details of this function: Why does the first arg 'f' get special treatment here?
If I'm interpreting this right, the log command has a mixture of substitution and positional formatting, which could be simplified to log('#%d %s', req.index, f, ...args)
, in which case I don't see the point of splitting out 'f' at all.
|
||
const quoteSingles = x => x.replace(/[']/g, '\\\'') | ||
const quoteBackquotes = x => x.replace(/[`]/g, '\\`') | ||
const formatObj = x => nu.inspect(x, {depth: Infinity, maxArrayLength: 10e3, breakLength: 100}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inspect
is a (awesome) Node utility that formats objects in a very readable way while still allowing them to be read via Node's interpreter. I've included a few options to ensure the output is less concise so it includes all of the data, but this is the workhorse that produces the fairly readable handlers directly from code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this different from JSON.stringify() ?
const omit = ks => obj => | ||
Object.keys(obj).reduce((acc, k) => ks.includes(k) ? acc : ({...acc, [k]: obj[k]}), {}) | ||
|
||
const promiseEvent = eventName => x => new Promise(resolve => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would "convert event to promise" be an accurate way to describe what this is doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. We're not transforming the event in any way. Instead, we're just waiting for it using the promise mechanism instead of a callback. "Promise event" here means, "promise me that you'll get an event in the future." I'm using promise in its verb form to return one in its noun form. Does that context make you think this name is a good choice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following. Not too surprising, since I don't really understand how events work. Also: I find curried functions to be an order of magnitude more difficult to read, so there's that too.
But this might be moot: I don't see that this is being used anywhere. Maybe it can be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since node supports "old style" require module semantics along with the now current import semantics, it uses the extension to determine which one you are using. At this time, import only works in "modules," which must have the .mjs extension.
Thanks for the reminder to update the README.
const omit = ks => obj => | ||
Object.keys(obj).reduce((acc, k) => ks.includes(k) ? acc : ({...acc, [k]: obj[k]}), {}) | ||
|
||
const promiseEvent = eventName => x => new Promise(resolve => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. We're not transforming the event in any way. Instead, we're just waiting for it using the promise mechanism instead of a callback. "Promise event" here means, "promise me that you'll get an event in the future." I'm using promise in its verb form to return one in its noun form. Does that context make you think this name is a good choice?
|
||
const quoteSingles = x => x.replace(/[']/g, '\\\'') | ||
const quoteBackquotes = x => x.replace(/[`]/g, '\\`') | ||
const formatObj = x => nu.inspect(x, {depth: Infinity, maxArrayLength: 10e3, breakLength: 100}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inspect
is a (awesome) Node utility that formats objects in a very readable way while still allowing them to be read via Node's interpreter. I've included a few options to ensure the output is less concise so it includes all of the data, but this is the workhorse that produces the fairly readable handlers directly from code.
req.startTimeMs = Date.now() | ||
req.index = requestIndex++ | ||
res.index = req.index | ||
req.log = (...formatArgs) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean the ...formatArgs
part, which is just variadic arguments in JS (probably like ES2015+).
No ticket - Test changes only. No code changes.
This creates a proxy to simulate API responses. The goal is to make UI tests faster and more reliable.
Most of the code is auto-generated from real API responses, so this change is smaller than it looks. You can ignore everything in the
handlers
directory, provided the code that generates those files looks sound.TODO:
Handlers should not be a set of static files. Instead, each test should define the handlers to be used for that test.