Skip to content

Commit

Permalink
feat: add support and tests for webpack (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-fenster authored and JustinBeckwith committed Feb 12, 2019
1 parent 1b47153 commit 29d5d85
Show file tree
Hide file tree
Showing 14 changed files with 411 additions and 5 deletions.
8 changes: 8 additions & 0 deletions .cirrus.yml
Expand Up @@ -9,6 +9,14 @@ system_test_task:
install_script: npm install
test_script: npm run system-test

browser_test_task:
container:
image: gmathieu/node-browsers
# the most popular image on Dockerhub with both node8, chromium, and
# all required dependencies
install_script: npm install
test_script: npm run browser-test

test_task:
container:
matrix:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,3 +6,4 @@ coverage
package-lock.json
yarn.lock
.vscode
dist/
62 changes: 62 additions & 0 deletions browser-test/browser-test-runner.ts
@@ -0,0 +1,62 @@
// Copyright 2019, Google, LLC.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as execa from 'execa';
import * as express from 'express';
import * as http from 'http';

const port = 7172;

async function listen(
app: express.Express, port: number): Promise<http.Server> {
return new Promise((resolve, reject) => {
const server = app.listen(port, (err: Error) => {
if (err) {
reject(err);
}
resolve(server);
});
});
}

// Starts a web server that browser tests will use, then runs actual browser
// tests.
async function main() {
const app = express();
app.get('/path', (req: express.Request, res: express.Response) => {
if (req.header('origin')) {
res.set('Access-Control-Allow-Origin', req.header('origin'));
}
res.send('response');
});
app.get('/querystring', (req: express.Request, res: express.Response) => {
if (req.header('origin')) {
res.set('Access-Control-Allow-Origin', req.header('origin'));
}
const query = req.query.query;
res.send(query || '');
});

const server = await listen(app, port);
console.log(`[http server] I'm listening on port ${port}! Starting karma.`);
const result = await execa('karma', ['start'], {stdio: 'inherit'});
server.close();
console.log(
`[http server] Karma has finished! I'm no longer listening on port ${
port}!`);
process.exit(result.failed ? 1 : 0);
}

main().catch(err => {
console.log('Error:', err);
});
21 changes: 21 additions & 0 deletions browser-test/test.browser.ts
@@ -0,0 +1,21 @@
import * as assert from 'assert';

import {request} from '../src/index';
const port = 7172; // should match the port defined in `webserver.ts`

describe('💻 browser tests', () => {
it('should just work from browser', async () => {
const result = await request({url: `http://localhost:${port}/path`});
assert.strictEqual(result.status, 200);
assert.strictEqual(result.data, 'response');
});

it('should pass querystring parameters from browser', async () => {
const result = await request({
url: `http://localhost:${port}/querystring`,
params: {query: 'value'}
});
assert.strictEqual(result.status, 200);
assert.strictEqual(result.data, 'value');
});
});
98 changes: 98 additions & 0 deletions karma.conf.js
@@ -0,0 +1,98 @@
/**
* Copyright 2019 Google LLC. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Karma configuration
// Use `npm run browser-test` to run browser tests with Karma.
const fs = require('fs');
const isDocker = require('is-docker')();

const webpackConfig = require('./webpack-tests.config.js');
process.env.CHROME_BIN = fs.existsSync('/usr/bin/chromium-browser')
? '/usr/bin/chromium-browser'
: require('puppeteer').executablePath();

module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',

// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],

// list of files / patterns to load in the browser
files: ['./browser-test/test.*.ts'],

// list of files / patterns to exclude
exclude: [],

// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'./src/*.ts': ['coverage'],
'./src/**/*.ts': ['coverage'],
'./browser-test/*.ts': ['webpack', 'sourcemap']
},

webpack: webpackConfig,

// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage', 'remap-coverage'],

coverageReporter: { type: 'in-memory' },
remapCoverageReporter: { html: './coverage' },

// web server port
port: 9876,

// enable / disable colors in the output (reporters and logs)
colors: true,

// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['ChromeCustom'],
customLaunchers: {
ChromeCustom: {
base: 'ChromeHeadless',
// We must disable the Chrome sandbox when running Chrome inside Docker (Chrome's sandbox needs
// more permissions than Docker allows by default)
flags: isDocker ? ['--no-sandbox'] : []
}
},

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,

// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,

// set correct MIME type when serving .ts files (already compiled to JavaScript):
mime: {
'text/javascript': ['ts']
}
});
};
23 changes: 21 additions & 2 deletions package.json
Expand Up @@ -19,7 +19,10 @@
"prepare": "npm run compile",
"pretest": "npm run compile",
"codecov": "nyc report --reporter=json && codecov -f coverage/*.json",
"commitlint": "git log -1 --pretty=%B | commitlint"
"commitlint": "git log -1 --pretty=%B | commitlint",
"webpack": "webpack",
"prebrowser-test": "npm run compile",
"browser-test": "node build/browser-test/browser-test-runner.js"
},
"repository": "JustinBeckwith/gaxios",
"keywords": [
Expand All @@ -30,6 +33,7 @@
"devDependencies": {
"@commitlint/cli": "^7.2.1",
"@commitlint/config-conventional": "^7.1.2",
"@types/express": "^4.16.1",
"@types/execa": "^0.9.0",
"@types/extend": "^3.0.0",
"@types/mocha": "^5.2.5",
Expand All @@ -42,19 +46,34 @@
"@types/tmp": "0.0.33",
"assert-rejects": "^1.0.0",
"codecov": "^3.0.4",
"express": "^4.16.4",
"execa": "^1.0.0",
"gts": "^0.9.0",
"is-docker": "^1.1.0",
"karma": "^4.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.2",
"karma-firefox-launcher": "^1.1.0",
"karma-mocha": "^1.3.0",
"karma-remap-coverage": "^0.1.5",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^3.0.5",
"mocha": "^5.2.0",
"mv": "^2.1.1",
"ncp": "^2.0.0",
"nock": "^9.6.0",
"null-loader": "^0.1.1",
"nyc": "^12.0.2",
"puppeteer": "^1.12.2",
"semantic-release": "^15.13.2",
"semistandard": "^13.0.1",
"sinon": "^7.1.1",
"source-map-support": "^0.5.6",
"tmp": "0.0.33",
"typescript": "~3.3.0"
"ts-loader": "^5.3.3",
"typescript": "~3.3.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3"
},
"dependencies": {
"abort-controller": "^2.0.2",
Expand Down
5 changes: 4 additions & 1 deletion src/gaxios.ts
Expand Up @@ -16,11 +16,14 @@ import {Agent} from 'https';
import fetch, {Response} from 'node-fetch';
import * as qs from 'querystring';
import * as stream from 'stream';
import {URL} from 'url';
import * as url from 'url';

import {GaxiosError, GaxiosOptions, GaxiosPromise, GaxiosResponse, Headers} from './common';
import {isBrowser} from './isbrowser';
import {getRetryConfig} from './retry';

const URL = isBrowser() ? window.URL : url.URL;

// tslint:disable-next-line variable-name no-any
let HttpsProxyAgent: any;

Expand Down
19 changes: 19 additions & 0 deletions src/isbrowser.ts
@@ -0,0 +1,19 @@
/**
* Copyright 2019 Google LLC. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export function isBrowser(): boolean {
return typeof (window) !== 'undefined';
}
6 changes: 5 additions & 1 deletion system-test/fixtures/sample/package.json
Expand Up @@ -18,6 +18,10 @@
"devDependencies": {
"@types/node": "^10.3.0",
"typescript": "^3.0.0",
"gts": "^0.9.0"
"gts": "^0.9.0",
"null-loader": "^0.1.1",
"ts-loader": "^5.3.3",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3"
}
}
53 changes: 53 additions & 0 deletions system-test/fixtures/sample/webpack.config.js
@@ -0,0 +1,53 @@
/**
* Copyright 2019 Google LLC. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Use `npm run webpack` to produce Webpack bundle for this library.

const path = require('path');

module.exports = {
entry: './src/index.ts',
resolve: {
extensions: ['.ts', '.js', '.json'],
alias: {
'../../package.json': path.resolve(__dirname, 'package.json')
}
},
output: {
filename: 'bundle.min.js',
path: path.resolve(__dirname, 'dist')
},
node: {
child_process: 'empty',
fs: 'empty',
crypto: 'empty'
},
module: {
rules: [
{
test: /node_modules\/https-proxy-agent\//,
use: 'null-loader'
},
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
mode: 'production',
plugins: []
};

0 comments on commit 29d5d85

Please sign in to comment.