Request hooks#2200
Conversation
|
❌ Tests for the commit 107f92f have failed. See details: |
|
❌ Tests for the commit 0f0dca7 have failed. See details: |
|
❌ Tests for the commit 97d450a have failed. See details: |
|
❌ Tests for the commit 4647454 have failed. See details: |
|
❌ Tests for the commit e2a94a2 have failed. See details: |
ba8df34 to
cf9a52c
Compare
|
✅ Tests for the commit cf9a52c have passed. See details: |
07b2215 to
6274729
Compare
|
❌ Tests for the commit 6274729 have failed. See details: |
|
@testcafe-build-bot \retest |
|
Let's start to review this PR. |
|
✅ Tests for the commit 6274729 have passed. See details: |
| getActualValueMsg: (value, type) => isNullOrUndefined(value) ? String(value) : type | ||
| }, | ||
|
|
||
| requestHookInheritor: { |
There was a problem hiding this comment.
I think it's better to call it isRequestHookSubclass.
There was a problem hiding this comment.
All conditions are named without is keyword: number, nonNegativeNumber and etc. See more details https://github.com/DevExpress/testcafe/blob/master/src/errors/runtime/type-assertions.js#L10.
But the term subclass is more relevant than inheritor for this context.
Links:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance
So, the final name - requestHookSubclass.
|
|
||
| RequestHook, | ||
|
|
||
| ResultPromise, |
There was a problem hiding this comment.
I feel we need to discuss why this thing is exported.
There was a problem hiding this comment.
Motivation:
Requests are asynchronous. It's impossible to check result of custom request hook without adding timeouts. For example, try to remove PromiseResult for this test - https://github.com/DevExpress/testcafe/pull/2200/files#diff-4b5df15c8ad0e18c0978bf61152150ceR33 and try to fix unstable.
It means that customer cannot create a custom request hook with convenient API.
|
|
||
| this.onResponseCallCountInternal = 0; | ||
|
|
||
| Object.defineProperty(this, 'onResponseCallCount', { |
There was a problem hiding this comment.
You can use ES6 class getter here. Also, IMHO it's better to name it responseHandlerCallCount (and use internalResponseHandlerCallCount for the internal property).
There was a problem hiding this comment.
You can use ES6 class getter here
Ok. Let it be.
Also, IMHO it's better to name it responseHandlerCallCount (and use internalResponseHandlerCallCount for the internal property).
It is not handler. It is method from base class. Simular as in Reporter plugin.
Variants: onResponseMethodCallCount, responseCallCount and etc.
So, I will keep it as is.
|
❌ Tests for the commit f7b28a3 have failed. See details: |
df26a43 to
5a0696a
Compare
|
❌ Tests for the commit 5a0696a have failed. See details: |
|
@testcafe-build-bot \retest |
|
❌ Tests for the commit 5a0696a have failed. See details: |
|
@testcafe-build-bot \retest |
|
✅ Tests for the commit 5a0696a have passed. See details: |
|
FPR |
|
✅ Tests for the commit 6fe36e5 have passed. See details: |
|
❌ Tests for the commit e09a61c have failed. See details: |
|
✅ Tests for the commit 0c61cd6 have passed. See details: |
|
❌ Tests for the commit b90bb56 have failed. See details: |
| constructor (name) { | ||
| super(pageUrl); | ||
|
|
||
| this.name = name; |
There was a problem hiding this comment.
it seems the name field is not used anywhere
| await t | ||
| .click(buttonSelector) | ||
| .expect(buttonSelector.textContent).eql('Done') | ||
| .expect(logger.contains(r => r.response.body === browserName)).ok(); |
There was a problem hiding this comment.
add check that other requests (except /get-browser-name) are not saved
| }); | ||
| } | ||
|
|
||
| onRequest (/*RequestEvent event*/) { |
There was a problem hiding this comment.
If this class is abstract this method should throw an error. If a subclass shouldn't do anything here they just should have an empty method
| hooks.forEach(hook => { | ||
| if (this.testRun.requestHooks.includes(hook)) { | ||
| remove(this.testRun.requestHooks, hook); | ||
| this.testRun._disposeRequestHook(hook); |
There was a problem hiding this comment.
I propose to encapsulate this login in testRun:
this.testRun.addRequestHook
this.testRun.removeRequestHook
// usage:
hooks.forEach(hook => this.testRun.addRequestHook(hook));
hooks.forEach(hook => this.testRun.removeRequestHook(hook));|
|
||
| this.requestHooks = Array.from(this.test.requestHooks); | ||
|
|
||
| this._initRequestHooks(); |
There was a problem hiding this comment.
Do we need that function that contains only one line? I guess inline this.requestHooks.forEach(hook => this._initRequestHook(hook)); call is good.
There was a problem hiding this comment.
It's debatable.
Compare two code parts. Which is more readable?
1
this.injectable.scripts.push('/testcafe-automation.js');
this.injectable.scripts.push('/testcafe-driver.js');
this.injectable.styles.push('/testcafe-ui-styles.css');
this.requestHooks = Array.from(this.test.requestHooks);
this._initRequestHooks();2
this.injectable.scripts.push('/testcafe-automation.js');
this.injectable.scripts.push('/testcafe-driver.js');
this.injectable.styles.push('/testcafe-ui-styles.css');
this.requestHooks = Array.from(this.test.requestHooks);
this.requestHooks.forEach(hook => this._initRequestHook(hook));There was a problem hiding this comment.
Personally, I Don't see much differences)
In the first case you have to keep in mind that you need to call the _initRequestHooks function after the this.requestHooks = .... In the second case it's obvious from the code.
| const pageUrl = 'http://localhost:3000/fixtures/api/es-next/request-hooks/pages/index.html'; | ||
| const logger = new RequestLogger(pageUrl); | ||
|
|
||
| fixture `RequestLogger` |
There was a problem hiding this comment.
It can be a unit test.
|
✅ Tests for the commit 443cce4 have passed. See details: |
|
FPR |
|
@miherlosev rebase to upstream please |
It will be do after hammerhead version will be updated. |
|
❌ Tests for the commit 77d24e3 have failed. See details: |
|
✅ Tests for the commit 77d24e3 have passed. See details: |
|
FPR |
|
@AndreyBelym Review but don't merge until hammerhead version was updated. |
|
❌ Tests for the commit 5b472c8 have failed. See details: |
|
Hi folks - I hope you'll pardon my question, but the fact that xhr request stubbing isn't already provided in testcafe makes me think I may be missing the point or something. Isn't it the case that, without this feature, you can only use testcafe for end-to-end tests? Or is there another way to stub xhr requests? Requiring my tests hit my production backend API will definitely slow things down. Is it, perhaps, about a flag in my application code on |
|
@timwis You can use proxy between testcafe and origin to redirect XHR requests (see https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--proxy-host). However, if you want to do that from your test code you'll need this feature. |
|
❌ Tests for the commit eceadab have failed. See details: |
|
❌ Tests for the commit f370d01 have failed. See details: |
|
@testcafe-build-bot \retest |
|
✅ Tests for the commit f370d01 have passed. See details: |
* Request hooks * fix Alex review issues * minor changes * rename 'sessionId ' to 'testRunId' for logged request (RequestLogger) * fix tests * use the current hammerhead version
Typedefs will be updated in a separate PR.
Feature has 2 parts: in testcafe and in hammerhead.
Firstly, the testcafe part will be reviewed. After that - the hammerhead (DevExpress/testcafe-hammerhead#1527).
For convenience,in this PR the hammerhead part used as module - see https://github.com/DevExpress/testcafe/compare/master...miherlosev:request_hooks?expand=1#diff-b9cfc7f2cdf78a7f4b91a753d10865a2R106.
Changes:
RequestMock,RequestLoggerandRequestHookclassesClientFunctionResultPromisetoReExecutablePromise.RequestHookConfigureAPIErrorclassassertThrowto testing helpers