From 41f393ae2ab00723be517816fa85a5db08c42462 Mon Sep 17 00:00:00 2001 From: offirgolan Date: Mon, 23 Jul 2018 16:50:01 -0700 Subject: [PATCH 1/6] feat: Wait for all handled requests to resolve via `.flush()` --- packages/@pollyjs/adapter/src/index.js | 22 +++++++++++++----- .../@pollyjs/core/src/-private/request.js | 3 ++- packages/@pollyjs/core/src/polly.js | 8 +++++++ packages/@pollyjs/utils/src/index.js | 1 + .../utils/src/utils/deferred-promise.js | 17 ++++++++++++++ .../tests/unit/utils/deferred-promise-test.js | 23 +++++++++++++++++++ 6 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 packages/@pollyjs/utils/src/utils/deferred-promise.js create mode 100644 packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js diff --git a/packages/@pollyjs/adapter/src/index.js b/packages/@pollyjs/adapter/src/index.js index 0afbbcfd..05e5b1f7 100644 --- a/packages/@pollyjs/adapter/src/index.js +++ b/packages/@pollyjs/adapter/src/index.js @@ -87,17 +87,27 @@ export default class Adapter { } } - handleRequest() { - return this[REQUEST_HANDLER](...arguments); + async handleRequest(request) { + const pollyRequest = this.polly.registerRequest(request); + + await pollyRequest.setup(); + + try { + const response = await this[REQUEST_HANDLER](pollyRequest); + + pollyRequest.promise.resolve(response); + + return response; + } catch (error) { + pollyRequest.promise.reject(error); + throw error; + } } - async [REQUEST_HANDLER](request) { + async [REQUEST_HANDLER](pollyRequest) { const { mode } = this.polly; - const pollyRequest = this.polly.registerRequest(request); let interceptor; - await pollyRequest.setup(); - if (pollyRequest.shouldIntercept) { interceptor = new Interceptor(); const response = await this.intercept(pollyRequest, interceptor); diff --git a/packages/@pollyjs/core/src/-private/request.js b/packages/@pollyjs/core/src/-private/request.js index 442b58c4..f106481f 100644 --- a/packages/@pollyjs/core/src/-private/request.js +++ b/packages/@pollyjs/core/src/-private/request.js @@ -6,7 +6,7 @@ import NormalizeRequest from '../utils/normalize-request'; import removeHostFromUrl from '../utils/remove-host-from-url'; import serializeRequestBody from '../utils/serialize-request-body'; import isAbsoluteUrl from 'is-absolute-url'; -import { assert, timestamp } from '@pollyjs/utils'; +import { assert, timestamp, DeferredPromise } from '@pollyjs/utils'; import HTTPBase from './http-base'; const { keys, freeze } = Object; @@ -29,6 +29,7 @@ export default class PollyRequest extends HTTPBase { this.recordingName = polly.recordingName; this.recordingId = polly.recordingId; this.requestArguments = freeze(request.requestArguments || []); + this.promise = DeferredPromise(); this[POLLY] = polly; /* diff --git a/packages/@pollyjs/core/src/polly.js b/packages/@pollyjs/core/src/polly.js index 14cb458e..6f078f4c 100644 --- a/packages/@pollyjs/core/src/polly.js +++ b/packages/@pollyjs/core/src/polly.js @@ -234,6 +234,14 @@ export default class Polly { } } + async flush() { + const NOOP = () => {}; + + await Promise.all( + this._requests.map(r => Promise.resolve(r.promise).then(NOOP, NOOP)) + ); + } + /** * @param {String|Function} nameOrFactory * @public diff --git a/packages/@pollyjs/utils/src/index.js b/packages/@pollyjs/utils/src/index.js index 91aca8e1..44723573 100644 --- a/packages/@pollyjs/utils/src/index.js +++ b/packages/@pollyjs/utils/src/index.js @@ -6,6 +6,7 @@ export { default as assert } from './utils/assert'; export { default as timeout } from './utils/timeout'; export { default as timestamp } from './utils/timestamp'; export { default as buildUrl } from './utils/build-url'; +export { default as DeferredPromise } from './utils/deferred-promise'; export { default as XHR } from './utils/xhr'; export { default as Fetch } from './utils/fetch'; diff --git a/packages/@pollyjs/utils/src/utils/deferred-promise.js b/packages/@pollyjs/utils/src/utils/deferred-promise.js new file mode 100644 index 00000000..13b724ba --- /dev/null +++ b/packages/@pollyjs/utils/src/utils/deferred-promise.js @@ -0,0 +1,17 @@ +/** + * Create a deferred promise with `resolve` and `reject` methods. + * + * @returns {Promise} + */ +export default function DeferredPromise() { + let resolve, reject; + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); + + promise.resolve = resolve; + promise.reject = reject; + + return promise; +} diff --git a/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js b/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js new file mode 100644 index 00000000..b198c3b7 --- /dev/null +++ b/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js @@ -0,0 +1,23 @@ +import DeferredPromise from '../../../src/utils/deferred-promise'; + +describe('Unit | Utils | DeferredPromise', function() { + it('should exist', function() { + expect(DeferredPromise).to.be.a('function'); + expect(DeferredPromise().resolve).to.be.a('function'); + expect(DeferredPromise().reject).to.be.a('function'); + }); + + it('should resolve when calling .resolve()', async function() { + const promise = DeferredPromise(); + + promise.resolve(42); + expect(await promise).to.equal(42); + }); + + it('should reject when calling .reject()', async function() { + const promise = DeferredPromise(); + + promise.reject(new Error('42')); + expect(async () => await promise).to.throw(Error, /42/); + }); +}); From c20a4dad78148ce50f14c5c6454e8356a7d7d37e Mon Sep 17 00:00:00 2001 From: offirgolan Date: Tue, 24 Jul 2018 09:51:45 -0700 Subject: [PATCH 2/6] test: Add tests and docs --- docs/api.md | 14 ++++++++++ .../@pollyjs/core/src/-private/request.js | 2 +- packages/@pollyjs/core/src/polly.js | 2 ++ .../utils/src/utils/deferred-promise.js | 19 +++++++------- .../tests/unit/utils/deferred-promise-test.js | 16 ++++++++---- tests/integration/adapter-tests.js | 26 +++++++++++++++++++ 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/docs/api.md b/docs/api.md index 753794f5..ba4151a6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -251,3 +251,17 @@ __Example__ ```js polly.disconnect(); ``` + +### flush + +Returns a Promise that resolves once all requests handled by Polly have resolved. + +| Param | Type | Description | +| --- | --- | --- | +| Returns | `Promise` |   | + +__Example__ + +```js +await polly.flush(); +``` diff --git a/packages/@pollyjs/core/src/-private/request.js b/packages/@pollyjs/core/src/-private/request.js index f106481f..e25755f1 100644 --- a/packages/@pollyjs/core/src/-private/request.js +++ b/packages/@pollyjs/core/src/-private/request.js @@ -29,7 +29,7 @@ export default class PollyRequest extends HTTPBase { this.recordingName = polly.recordingName; this.recordingId = polly.recordingId; this.requestArguments = freeze(request.requestArguments || []); - this.promise = DeferredPromise(); + this.promise = new DeferredPromise(); this[POLLY] = polly; /* diff --git a/packages/@pollyjs/core/src/polly.js b/packages/@pollyjs/core/src/polly.js index 6f078f4c..99415940 100644 --- a/packages/@pollyjs/core/src/polly.js +++ b/packages/@pollyjs/core/src/polly.js @@ -238,6 +238,8 @@ export default class Polly { const NOOP = () => {}; await Promise.all( + // The NOOP is there to handle both a resolved and rejected promise + // to ensure the promise resolves regardless of the outcome. this._requests.map(r => Promise.resolve(r.promise).then(NOOP, NOOP)) ); } diff --git a/packages/@pollyjs/utils/src/utils/deferred-promise.js b/packages/@pollyjs/utils/src/utils/deferred-promise.js index 13b724ba..adb3e54f 100644 --- a/packages/@pollyjs/utils/src/utils/deferred-promise.js +++ b/packages/@pollyjs/utils/src/utils/deferred-promise.js @@ -3,15 +3,16 @@ * * @returns {Promise} */ -export default function DeferredPromise() { - let resolve, reject; - const promise = new Promise((_resolve, _reject) => { - resolve = _resolve; - reject = _reject; - }); +export default class DeferredPromise extends Promise { + constructor() { + let resolve, reject; - promise.resolve = resolve; - promise.reject = reject; + super((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); - return promise; + this.resolve = resolve; + this.reject = reject; + } } diff --git a/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js b/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js index b198c3b7..d278796b 100644 --- a/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js +++ b/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js @@ -3,21 +3,27 @@ import DeferredPromise from '../../../src/utils/deferred-promise'; describe('Unit | Utils | DeferredPromise', function() { it('should exist', function() { expect(DeferredPromise).to.be.a('function'); - expect(DeferredPromise().resolve).to.be.a('function'); - expect(DeferredPromise().reject).to.be.a('function'); + expect(new DeferredPromise().resolve).to.be.a('function'); + expect(new DeferredPromise().reject).to.be.a('function'); }); it('should resolve when calling .resolve()', async function() { - const promise = DeferredPromise(); + const promise = new DeferredPromise(); promise.resolve(42); expect(await promise).to.equal(42); }); it('should reject when calling .reject()', async function() { - const promise = DeferredPromise(); + const promise = new DeferredPromise(); promise.reject(new Error('42')); - expect(async () => await promise).to.throw(Error, /42/); + + try { + await promise; + } catch (error) { + expect(error).to.be.an('error'); + expect(error.message).to.equal('42'); + } }); }); diff --git a/tests/integration/adapter-tests.js b/tests/integration/adapter-tests.js index 352fd494..dcaf178e 100644 --- a/tests/integration/adapter-tests.js +++ b/tests/integration/adapter-tests.js @@ -99,4 +99,30 @@ export default function adapterTests() { expect(await persister.find(recordingId)).to.be.null; expect(responseCalled).to.be.true; }); + + it('should have responses after flushing', async function() { + const { server } = this.polly; + const requests = []; + + server.get(this.recordUrl()).intercept(async (req, res) => { + requests.push(req); + await server.timeout(5 * requests.length); + res.sendStatus(200); + }); + + this.fetchRecord(); + this.fetchRecord(); + this.fetchRecord(); + + // Wait for all requests to be made + // (Puppeteer adapter takes some time to make the actual request) + while (requests.length !== 3) { + await server.timeout(5); + } + + await this.polly.flush(); + + expect(requests).to.have.lengthOf(3); + requests.forEach(request => expect(request.didRespond).to.be.true); + }); } From 5fcfc3f012211c2d4664660f57011e75b67b82a0 Mon Sep 17 00:00:00 2001 From: offirgolan Date: Wed, 25 Jul 2018 12:53:31 -0700 Subject: [PATCH 3/6] refactor: Move DeferredPromise into core --- packages/@pollyjs/core/src/-private/request.js | 3 ++- .../@pollyjs/{utils => core}/src/utils/deferred-promise.js | 2 -- .../{utils => core}/tests/unit/utils/deferred-promise-test.js | 0 packages/@pollyjs/utils/src/index.js | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) rename packages/@pollyjs/{utils => core}/src/utils/deferred-promise.js (92%) rename packages/@pollyjs/{utils => core}/tests/unit/utils/deferred-promise-test.js (100%) diff --git a/packages/@pollyjs/core/src/-private/request.js b/packages/@pollyjs/core/src/-private/request.js index e25755f1..5d713ce7 100644 --- a/packages/@pollyjs/core/src/-private/request.js +++ b/packages/@pollyjs/core/src/-private/request.js @@ -5,8 +5,9 @@ import PollyResponse from './response'; import NormalizeRequest from '../utils/normalize-request'; import removeHostFromUrl from '../utils/remove-host-from-url'; import serializeRequestBody from '../utils/serialize-request-body'; +import DeferredPromise from '../utils/deferred-promise'; import isAbsoluteUrl from 'is-absolute-url'; -import { assert, timestamp, DeferredPromise } from '@pollyjs/utils'; +import { assert, timestamp } from '@pollyjs/utils'; import HTTPBase from './http-base'; const { keys, freeze } = Object; diff --git a/packages/@pollyjs/utils/src/utils/deferred-promise.js b/packages/@pollyjs/core/src/utils/deferred-promise.js similarity index 92% rename from packages/@pollyjs/utils/src/utils/deferred-promise.js rename to packages/@pollyjs/core/src/utils/deferred-promise.js index adb3e54f..dc560a2b 100644 --- a/packages/@pollyjs/utils/src/utils/deferred-promise.js +++ b/packages/@pollyjs/core/src/utils/deferred-promise.js @@ -1,7 +1,5 @@ /** * Create a deferred promise with `resolve` and `reject` methods. - * - * @returns {Promise} */ export default class DeferredPromise extends Promise { constructor() { diff --git a/packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js b/packages/@pollyjs/core/tests/unit/utils/deferred-promise-test.js similarity index 100% rename from packages/@pollyjs/utils/tests/unit/utils/deferred-promise-test.js rename to packages/@pollyjs/core/tests/unit/utils/deferred-promise-test.js diff --git a/packages/@pollyjs/utils/src/index.js b/packages/@pollyjs/utils/src/index.js index 44723573..91aca8e1 100644 --- a/packages/@pollyjs/utils/src/index.js +++ b/packages/@pollyjs/utils/src/index.js @@ -6,7 +6,6 @@ export { default as assert } from './utils/assert'; export { default as timeout } from './utils/timeout'; export { default as timestamp } from './utils/timestamp'; export { default as buildUrl } from './utils/build-url'; -export { default as DeferredPromise } from './utils/deferred-promise'; export { default as XHR } from './utils/xhr'; export { default as Fetch } from './utils/fetch'; From 05e8f580c1a0875ea480f9aa0c602833f613c641 Mon Sep 17 00:00:00 2001 From: offirgolan Date: Thu, 26 Jul 2018 10:36:19 -0700 Subject: [PATCH 4/6] feat: Add more hooks to support puppeteer adapter --- .../@pollyjs/adapter-puppeteer/src/index.js | 54 +++++++++++++++++-- .../tests/integration/adapter-test.js | 36 +++++++++++++ packages/@pollyjs/adapter/src/index.js | 51 ++++++++++++++++-- .../@pollyjs/core/src/-private/request.js | 6 +-- tests/integration/adapter-tests.js | 33 ++++++------ 5 files changed, 151 insertions(+), 29 deletions(-) diff --git a/packages/@pollyjs/adapter-puppeteer/src/index.js b/packages/@pollyjs/adapter-puppeteer/src/index.js index 3b3faed0..c35c0eae 100644 --- a/packages/@pollyjs/adapter-puppeteer/src/index.js +++ b/packages/@pollyjs/adapter-puppeteer/src/index.js @@ -1,6 +1,7 @@ import Adapter from '@pollyjs/adapter'; const LISTENERS = Symbol(); +const POLLY_REQUEST = Symbol(); const PASSTHROUGH_PROMISE = Symbol(); const PASSTHROUGH_PROMISES = Symbol(); const PASSTHROUGH_REQ_ID_HEADER = 'x-pollyjs-passthrough-request-id'; @@ -73,17 +74,30 @@ export default class PuppeteerAdapter extends Adapter { const request = response.request(); // Resolve the passthrough promise with the response if it exists - request[PASSTHROUGH_PROMISE] && + if (request[PASSTHROUGH_PROMISE]) { request[PASSTHROUGH_PROMISE].resolve(response); - - delete request[PASSTHROUGH_PROMISE]; + delete request[PASSTHROUGH_PROMISE]; + } + }, + requestfinished: request => { + // Resolve the deferred pollyRequest promise if it exists + if (request[POLLY_REQUEST]) { + request[POLLY_REQUEST].promise.resolve(); + delete request[POLLY_REQUEST]; + } }, requestfailed: request => { // Reject the passthrough promise with the error object if it exists - request[PASSTHROUGH_PROMISE] && + if (request[PASSTHROUGH_PROMISE]) { request[PASSTHROUGH_PROMISE].reject(request.failure()); + delete request[PASSTHROUGH_PROMISE]; + } - delete request[PASSTHROUGH_PROMISE]; + // Reject the deferred pollyRequest promise with the error object if it exists + if (request[POLLY_REQUEST]) { + request[POLLY_REQUEST].promise.reject(request.failure()); + delete request[POLLY_REQUEST]; + } }, close: () => this[LISTENERS].delete(page) }); @@ -91,6 +105,36 @@ export default class PuppeteerAdapter extends Adapter { this._callListenersWith('prependListener', page); } + onRequest(pollyRequest) { + const [request] = pollyRequest.requestArguments; + + /* + Create an access point to the `pollyRequest` so it can be accessed from + the emitted page events + */ + request[POLLY_REQUEST] = pollyRequest; + } + + /** + * Override the onRequestFinished logic as it doesn't apply to this adapter. + * Instead, that logic is re-implemented via the `requestfinished` page + * event. + * + * @override + */ + onRequestFinished() {} + + /** + * Abort the request on failure. The parent `onRequestFailed` has been + * re-implemented via the `requestfailed` page event. + * @override + */ + async onRequestFailed(pollyRequest) { + const [request] = pollyRequest.requestArguments; + + await request.abort(); + } + async onRecord(pollyRequest) { await this.passthroughRequest(pollyRequest); await this.persister.recordRequest(pollyRequest); diff --git a/packages/@pollyjs/adapter-puppeteer/tests/integration/adapter-test.js b/packages/@pollyjs/adapter-puppeteer/tests/integration/adapter-test.js index 8f9000c5..913665ce 100644 --- a/packages/@pollyjs/adapter-puppeteer/tests/integration/adapter-test.js +++ b/packages/@pollyjs/adapter-puppeteer/tests/integration/adapter-test.js @@ -64,4 +64,40 @@ describe('Integration | Puppeteer Adapter', function() { setupPolly.afterEach(); adapterTests(); + + it('should have resolved requests after flushing', async function() { + // Timeout after 500ms since we could have a hanging while loop + this.timeout(500); + + const { server } = this.polly; + const requests = []; + const resolved = []; + let i = 1; + + server + .get(this.recordUrl()) + .intercept(async (req, res) => { + await server.timeout(5); + res.sendStatus(200); + }) + .on('request', req => requests.push(req)); + + this.page.on('requestfinished', () => resolved.push(i++)); + + this.fetchRecord(); + this.fetchRecord(); + this.fetchRecord(); + + // Since it takes time for Puppeteer to execute the request in the browser's + // context, we have to wait until the requests have been made. + while (requests.length !== 3) { + await server.timeout(5); + } + + await this.polly.flush(); + + expect(requests).to.have.lengthOf(3); + requests.forEach(request => expect(request.didRespond).to.be.true); + expect(resolved).to.have.members([1, 2, 3]); + }); }); diff --git a/packages/@pollyjs/adapter/src/index.js b/packages/@pollyjs/adapter/src/index.js index 05e5b1f7..db6b74de 100644 --- a/packages/@pollyjs/adapter/src/index.js +++ b/packages/@pollyjs/adapter/src/index.js @@ -91,15 +91,16 @@ export default class Adapter { const pollyRequest = this.polly.registerRequest(request); await pollyRequest.setup(); + await this.onRequest(pollyRequest); try { - const response = await this[REQUEST_HANDLER](pollyRequest); + const result = await this[REQUEST_HANDLER](pollyRequest); - pollyRequest.promise.resolve(response); + await this.onRequestFinished(pollyRequest, result); - return response; + return result; } catch (error) { - pollyRequest.promise.reject(error); + await this.onRequestFailed(pollyRequest, error); throw error; } } @@ -213,6 +214,7 @@ export default class Adapter { ); } + /* Required Hooks */ onConnect() { this.assert('Must implement the `onConnect` hook.', false); } @@ -221,19 +223,60 @@ export default class Adapter { this.assert('Must implement the `onDisconnect` hook.', false); } + /** + * @param {PollyRequest} pollyRequest + * @returns {*} + */ onRecord() { this.assert('Must implement the `onRecord` hook.', false); } + /** + * @param {PollyRequest} pollyRequest + * @param {Object} normalizedResponse The normalized response generated from the recording entry + * @param {Object} recordingEntry The entire recording entry + * @returns {*} + */ onReplay() { this.assert('Must implement the `onReplay` hook.', false); } + /** + * @param {PollyRequest} pollyRequest + * @param {PollyResponse} response + * @returns {*} + */ onIntercept() { this.assert('Must implement the `onIntercept` hook.', false); } + /** + * @param {PollyRequest} pollyRequest + * @returns {*} + */ onPassthrough() { this.assert('Must implement the `onPassthrough` hook.', false); } + + /* Other Hooks */ + /** + * @param {PollyRequest} pollyRequest + */ + onRequest() {} + + /** + * @param {PollyRequest} pollyRequest + * @param {*} result The returned result value from the request handler + */ + onRequestFinished(pollyRequest, result) { + pollyRequest.promise.resolve(result); + } + + /** + * @param {PollyRequest} pollyRequest + * @param {Error} error + */ + onRequestFailed(pollyRequest, error) { + pollyRequest.promise.reject(error); + } } diff --git a/packages/@pollyjs/core/src/-private/request.js b/packages/@pollyjs/core/src/-private/request.js index f9fc4559..be7419de 100644 --- a/packages/@pollyjs/core/src/-private/request.js +++ b/packages/@pollyjs/core/src/-private/request.js @@ -56,11 +56,7 @@ export default class PollyRequest extends HTTPBase { get absoluteUrl() { const { url } = this; - if (!isAbsoluteUrl(url)) { - return new URL(url).href; - } - - return url; + return isAbsoluteUrl(url) ? url : new URL(url).href; } get protocol() { diff --git a/tests/integration/adapter-tests.js b/tests/integration/adapter-tests.js index dcaf178e..05d6e243 100644 --- a/tests/integration/adapter-tests.js +++ b/tests/integration/adapter-tests.js @@ -100,29 +100,32 @@ export default function adapterTests() { expect(responseCalled).to.be.true; }); - it('should have responses after flushing', async function() { + it('should have resolved requests after flushing', async function() { + // The puppeteer adapter has its own implementation of this test + if (this.polly.adapters.has('puppeteer')) { + this.skip(); + } + const { server } = this.polly; const requests = []; + const resolved = []; - server.get(this.recordUrl()).intercept(async (req, res) => { - requests.push(req); - await server.timeout(5 * requests.length); - res.sendStatus(200); - }); - - this.fetchRecord(); - this.fetchRecord(); - this.fetchRecord(); + server + .get(this.recordUrl()) + .intercept(async (req, res) => { + await server.timeout(5); + res.sendStatus(200); + }) + .on('request', req => requests.push(req)); - // Wait for all requests to be made - // (Puppeteer adapter takes some time to make the actual request) - while (requests.length !== 3) { - await server.timeout(5); - } + this.fetchRecord().then(() => resolved.push(1)); + this.fetchRecord().then(() => resolved.push(2)); + this.fetchRecord().then(() => resolved.push(3)); await this.polly.flush(); expect(requests).to.have.lengthOf(3); requests.forEach(request => expect(request.didRespond).to.be.true); + expect(resolved).to.have.members([1, 2, 3]); }); } From 2fffa9ad6d76b5f07ad5a9921b46527e08dfc828 Mon Sep 17 00:00:00 2001 From: offirgolan Date: Thu, 26 Jul 2018 14:53:32 -0700 Subject: [PATCH 5/6] chore: Cleanup test configs --- package.json | 6 ++++-- testem.js | 7 +++---- tests/mocha.opts | 3 +++ 3 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 tests/mocha.opts diff --git a/package.json b/package.json index a4c26dab..612efea6 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,16 @@ "clean": "lerna run clean --parallel", "bootstrap": "lerna bootstrap", "format": "lerna run format", - "lint": "lerna exec --bail=false -- yarn run lint", + "lint": "lerna exec --bail=false --stream --no-prefix -- yarn run lint", "pretest": "yarn server:build", "pretest:ci": "yarn pretest", "test": "testem", "test:ci": "testem ci", "test:build": "lerna run test:build --parallel", "test:clean": "rimraf packages/@pollyjs/*/build", - "test:ember": "lerna run test --scope=@pollyjs/ember", + "test:node": "mocha --opts tests/mocha.opts", + "test:jest": "jest", + "test:ember": "lerna run test --stream --no-prefix --scope=@pollyjs/ember", "server:build": "yarn build --scope=@pollyjs/node-server --scope=@pollyjs/utils", "docs:serve": "docsify serve ./docs", "docs:publish": "gh-pages --dist docs --dotfiles --message 'chore: Publish docs'", diff --git a/testem.js b/testem.js index e1e97534..5d1a6cdc 100644 --- a/testem.js +++ b/testem.js @@ -15,7 +15,7 @@ module.exports = { './tests/*', './tests/!(recordings)/**/*', './packages/@pollyjs/*/src/**/*', - './packages/@pollyjs/*/tests/*/*' + './packages/@pollyjs/*/tests/**/*' ], serve_files: ['./packages/@pollyjs/*/build/browser/*.js'], browser_args: { @@ -33,12 +33,11 @@ module.exports = { middleware: [attachMiddleware], launchers: { Node: { - command: - 'mocha ./packages/@pollyjs/*/build/node/*.js --ui bdd --reporter tap --require tests/node-setup.js', + command: 'yarn test:node --reporter tap', protocol: 'tap' }, Jest: { - command: 'jest', + command: 'yarn test:jest', protocol: 'tap' }, Ember: { diff --git a/tests/mocha.opts b/tests/mocha.opts new file mode 100644 index 00000000..02ee2222 --- /dev/null +++ b/tests/mocha.opts @@ -0,0 +1,3 @@ +./packages/@pollyjs/*/build/node/*.js +--ui bdd +--require tests/node-setup.js From 0bbfd40b5d36e40ff0aca6034c17deebed6d5c11 Mon Sep 17 00:00:00 2001 From: offirgolan Date: Thu, 26 Jul 2018 15:19:37 -0700 Subject: [PATCH 6/6] fix: Resolve with the request's response --- packages/@pollyjs/adapter-puppeteer/src/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/@pollyjs/adapter-puppeteer/src/index.js b/packages/@pollyjs/adapter-puppeteer/src/index.js index c35c0eae..c94b7287 100644 --- a/packages/@pollyjs/adapter-puppeteer/src/index.js +++ b/packages/@pollyjs/adapter-puppeteer/src/index.js @@ -82,7 +82,7 @@ export default class PuppeteerAdapter extends Adapter { requestfinished: request => { // Resolve the deferred pollyRequest promise if it exists if (request[POLLY_REQUEST]) { - request[POLLY_REQUEST].promise.resolve(); + request[POLLY_REQUEST].promise.resolve(request.response()); delete request[POLLY_REQUEST]; } }, @@ -127,6 +127,7 @@ export default class PuppeteerAdapter extends Adapter { /** * Abort the request on failure. The parent `onRequestFailed` has been * re-implemented via the `requestfailed` page event. + * * @override */ async onRequestFailed(pollyRequest) {