Skip to content
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

tests(build): use firehouse smoke test runner to test bundle #9791

Merged
merged 37 commits into from
Oct 11, 2019
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a787ae4
tests(smoke): script to run smoke tests in devtools
connorjclark Jul 30, 2019
b43908a
working in canary
connorjclark Jul 30, 2019
fe26eb6
.
connorjclark Jul 30, 2019
d031248
skip messages.
connorjclark Jul 30, 2019
247676a
fix some edge cases re: busy page
connorjclark Jul 30, 2019
d6f844a
pass config
connorjclark Jul 30, 2019
11abbf8
comment
connorjclark Jul 30, 2019
909c770
firehouse
connorjclark Jul 31, 2019
b1be9a3
use dt test runner
connorjclark Aug 1, 2019
269334b
make regex work
connorjclark Aug 2, 2019
288a788
tmp
connorjclark Aug 2, 2019
9ee88a1
remove old code
connorjclark Aug 2, 2019
d569c9c
update roll
connorjclark Aug 2, 2019
2467ed1
Merge remote-tracking branch 'origin/master' into smokehouse-dt
connorjclark Oct 4, 2019
dac50ab
fix
connorjclark Oct 4, 2019
40d0b64
delete old test
connorjclark Oct 4, 2019
59d8bf2
fix
connorjclark Oct 4, 2019
480d330
bundle test
connorjclark Oct 5, 2019
4355577
yarn test-bundle
connorjclark Oct 5, 2019
fb011b0
rm unneeded cache stuff
connorjclark Oct 5, 2019
b6d9640
casing
connorjclark Oct 5, 2019
30c830b
comment
connorjclark Oct 5, 2019
5e7928b
ws
connorjclark Oct 5, 2019
e94b3ef
comment
connorjclark Oct 5, 2019
465cdb9
coment
connorjclark Oct 5, 2019
2df073b
ws
connorjclark Oct 5, 2019
8200096
ts
connorjclark Oct 5, 2019
6b2ae18
build-all
connorjclark Oct 5, 2019
e70eefd
rm devtools stuff
connorjclark Oct 5, 2019
0130eec
rename
connorjclark Oct 5, 2019
fac34aa
rm async
connorjclark Oct 5, 2019
0aa202e
globalThis -> global
connorjclark Oct 5, 2019
63e677b
pr
connorjclark Oct 7, 2019
f60c32f
comment
connorjclark Oct 7, 2019
e241388
comment
connorjclark Oct 7, 2019
893c5a3
urlFilterRegex
connorjclark Oct 11, 2019
7fdddd0
file comment
connorjclark Oct 11, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ script:
- yarn test-clients
- yarn test-viewer
- yarn test-lantern
- yarn test-bundle
- yarn i18n:checks
- yarn dogfood-lhci
before_cache:
Expand Down
66 changes: 66 additions & 0 deletions build/tests/bundle-smoke-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* @license Copyright 2019 Google Inc. 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 strict';

const fs = require('fs');
const {promisify} = require('util');
const {execFile} = require('child_process');
const execFileAsync = promisify(execFile);
const firehouse = require('../../lighthouse-cli/test/smokehouse/firehouse.js');
const bundleBuilder = require('../build-bundle.js');
const {server, serverForOffline} = require('../../lighthouse-cli/test/fixtures/static-server.js');

const testEntryPath = `${__dirname}/../../lighthouse-core/index.js`;
const testDistPath = `${__dirname}/../../dist/test-bundle.js`;

/**
* Run Lighthouse using a CLI that shims lighthouse-core with the output of the bundler.
* @param {string} url
* @param {LH.Config.Json} config
*/
async function runLighthouseFromMinifiedBundle(url, config) {
const configPath = `${__dirname}/../../.tmp/bundle-smoke-test-config.json`;
const lhrPath = `${__dirname}/../../.tmp/bundle-smoke-test-lhr.json`;
const gatherPath = `${__dirname}/../../.tmp/bundle-smoke-test-gather`;

fs.writeFileSync(configPath, JSON.stringify(config));

await execFileAsync('node', [
`${__dirname}/bundled-lighthouse-cli.js`,
url,
`--config-path=${configPath}`,
`-GA=${gatherPath}`,
'--output=json',
`--output-path=${lhrPath}`,
]);

const lhr = JSON.parse(fs.readFileSync(lhrPath, 'utf-8'));
const artifacts = JSON.parse(fs.readFileSync(`${gatherPath}/artifacts.json`, 'utf-8'));

return {
lhr,
artifacts,
};
}

async function main() {
await bundleBuilder.build(testEntryPath, testDistPath);

server.listen(10200, 'localhost');
serverForOffline.listen(10503, 'localhost');

const results = await firehouse.runSmokes({
runLighthouse: runLighthouseFromMinifiedBundle,
filter: /byte|dbw/,
});

await new Promise(resolve => server.close(resolve));
await new Promise(resolve => serverForOffline.close(resolve));

process.exit(results.success ? 0 : 1);
}

main();
88 changes: 88 additions & 0 deletions build/tests/bundled-lighthouse-cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* @license Copyright 2019 Google Inc. 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 strict';

const fs = require('fs');
const path = require('path');
const mkdirp = require('mkdirp');
const rimraf = require('rimraf');
const ChromeProtocol = require('../../lighthouse-core/gather/connections/cri.js');

const LH_ROOT = path.resolve(__dirname, '../..');
const corePath = `${LH_ROOT}/lighthouse-core/index.js`;

// Oh yeahhhhh this works. Think of this as `requireBundled('../../lighthouse-core/index.js')`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha I don't know what this means but it's hilarious :)

const lighthouse = (function getLighthouseCoreBundled() {
// The eval will assign to `require`. Normally, that would be the require on the global object.
// This `let` protects the global reference to the native require.
// Doesn't need to have any value, but for good measure define a function that explicitly forbids
// its own usage.
// To be further convinced that this works (that the un-bundled files are not being loaded),
// add some console.log's somewhere like `driver.js`, and
// run `node build/tests/bundled-lighthouse-cli.js https://www.example.com`. You won't see them.
/* eslint-disable-next-line */
let require = () => {
throw new Error('illegal require');
};

const lighthouseBundledCode = fs.readFileSync('dist/test-bundle.js', 'utf-8')
// Some modules are impossible to bundle. So we cheat by leaning on global.
// cri.js will be able to use native require. It's a minor defect - it means that some usages
// of lh-error.js will not come from the bundled code.
// TODO: use `globalThis` when we drop Node 10.
.replace('new ChromeProtocol', 'new global.ChromeProtocol')
// Needed for asset-saver.js.
.replace(/mkdirp\./g, 'global.mkdirp.')
.replace(/rimraf\./g, 'global.rimraf.')
.replace(/fs\.(writeFileSync|createWriteStream)/g, 'global.$&');

/* eslint-disable no-undef */
// @ts-ignore
global.ChromeProtocol = ChromeProtocol;
// @ts-ignore
global.mkdirp = mkdirp;
// @ts-ignore
global.rimraf = rimraf;
// @ts-ignore
global.fs = fs;
/* eslint-enable no-undef */

const bundledLighthouseRequire = eval(lighthouseBundledCode);
connorjclark marked this conversation as resolved.
Show resolved Hide resolved

// Find the lighthouse module.
// Every module is given an id (starting at 1). The core lighthouse module
// is the only module that is a function named `lighthouse`.
/** @type {import('../../lighthouse-core/index.js')} */
let lighthouse;
for (let i = 1; i < 1000; i++) {
patrickhulce marked this conversation as resolved.
Show resolved Hide resolved
const module = bundledLighthouseRequire(i);
if (module.name === 'lighthouse') {
lighthouse = module;
break;
}
}

// @ts-ignore
if (!lighthouse) throw new Error('could not find lighthouse module');

return lighthouse;
})();

// Shim the core module with the bundled code.

// @ts-ignore
lighthouse.__PATCHED__ = true;
require.cache[corePath] = {
exports: lighthouse,
};

// @ts-ignore
if (!require('../../lighthouse-core/index.js').__PATCHED__) {
throw new Error('error patching core module');
}

// Kick off the CLI.
require('../../lighthouse-cli/index.js');
68 changes: 68 additions & 0 deletions lighthouse-cli/test/smokehouse/firehouse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @license Copyright 2019 Google Inc. 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 strict';

/**
* @fileoverview Smoke test runner.
* Used to test channels other than npm (`run-smoke.js` handles that).
* Supports skipping and modifiying expectations to match the environment.
*/

/* eslint-disable no-console */

const log = require('lighthouse-logger');
const smokeTests = require('./smoke-test-dfns.js');
const {collateResults, report} = require('./smokehouse-report.js');

/**
* @param {Smokehouse.FirehouseOptions} options
*/
async function runSmokes(options) {
const {runLighthouse, filter, skip, modify} = options;

let passingCount = 0;
let failingCount = 0;

for (const test of smokeTests) {
for (const expected of test.expectations) {
if (filter && !expected.lhr.requestedUrl.match(filter)) {
connorjclark marked this conversation as resolved.
Show resolved Hide resolved
continue;
}

console.log(`====== ${expected.lhr.requestedUrl} ======`);
const reasonToSkip = skip && skip(test, expected);
if (reasonToSkip) {
console.log(`skipping: ${reasonToSkip}`);
continue;
}

modify && modify(test, expected);
const results = await runLighthouse(expected.lhr.requestedUrl, test.config);
console.log(`Asserting expected results match those found. (${expected.lhr.requestedUrl})`);
const collated = collateResults(results, expected);
const counts = report(collated);
passingCount += counts.passed;
failingCount += counts.failed;
}
}

if (passingCount) {
console.log(log.greenify(`${passingCount} passing`));
}
if (failingCount) {
console.log(log.redify(`${failingCount} failing`));
}

return {
success: passingCount > 0 && failingCount === 0,
passingCount,
failingCount,
};
}

module.exports = {
runSmokes,
};
2 changes: 1 addition & 1 deletion lighthouse-core/lib/asset-saver.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function stringifyReplacer(key, value) {
}

/**
* Save artifacts object mostly to single file located at basePath/artifacts.log.
* Save artifacts object mostly to single file located at basePath/artifacts.json.
* Also save the traces & devtoolsLogs to their own files
* @param {LH.Artifacts} artifacts
* @param {string} basePath
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"debug": "node --inspect-brk ./lighthouse-cli/index.js",
"start": "node ./lighthouse-cli/index.js",
"test": "yarn diff:sample-json && yarn lint --quiet && yarn unit && yarn type-check",
"test-bundle": "node build/tests/bundle-smoke-test.js",
"test-clients": "jest \"clients/\"",
"test-viewer": "yarn unit-viewer && jest lighthouse-viewer/test/viewer-test-pptr.js",
"test-lantern": "bash lighthouse-core/scripts/test-lantern.sh",
Expand Down
7 changes: 7 additions & 0 deletions types/smokehouse.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,11 @@
config: LH.Config.Json;
batch: string;
}

export interface FirehouseOptions {
runLighthouse: (url: string, config: LH.Config.Json) => Promise<Omit<LH.RunnerResult, 'report'>>;
filter?: RegExp;
skip?: (test: TestDfn, expectation: ExpectedRunnerResult) => string | false;
modify?: (test: TestDfn, expectation: ExpectedRunnerResult) => void;
}
}