Skip to content

Commit

Permalink
Use v8 Stack Trace API
Browse files Browse the repository at this point in the history
  • Loading branch information
ebidel committed Sep 27, 2016
1 parent 13ab3c1 commit 62d8d96
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 34 deletions.
18 changes: 11 additions & 7 deletions lighthouse-core/audits/dobetterweb/no-datenow.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,19 @@ class NoDateNowAudit extends Audit {
}

const pageHost = url.parse(artifacts.URL.finalUrl).host;

// Filter out Date.now() usage from scripts on other domains.
const results = artifacts.DateNowUse.errors.reduce((prev, err) => {
if (url.parse(err.url).host === pageHost) {
err.url = `${JSON.stringify(err)}`;
prev.push(err);
// Filter out Date.now() usage if script was on another host or an error with
// the same url:line:col combo has already been seen.
const results = artifacts.DateNowUse.dateNowUses.reduce((prev, err) => {
const jsonStr = JSON.stringify(err);
if (url.parse(err.url).host === pageHost && prev.indexOf(jsonStr) === -1) {
prev.push(jsonStr);
}
return prev;
}, []);
}, []).map(err => {
err = JSON.parse(err);
err.misc = `(line: ${err.line}, col: ${err.col})`;
return err;
});

return NoDateNowAudit.generateAuditResult({
rawValue: results.length === 0,
Expand Down
6 changes: 5 additions & 1 deletion lighthouse-core/formatters/partials/url-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
.http-resource__url {
margin-right: 8px;
}
.http-resource__protocol {
.http-resource__protocol,
.http-resource__misc {
color: #999;
}
</style>
Expand All @@ -19,6 +20,9 @@
{{#if this.protocol}}
<span class="http-resource__protocol">({{this.protocol}})</span>
{{/if}}
{{#if this.misc}}
<span class="http-resource__misc">{{this.misc}}</span>
{{/if}}
</div>
{{/each}}
</details>
Expand Down
33 changes: 17 additions & 16 deletions lighthouse-core/gather/gatherers/dobetterweb/datenow.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,22 @@ const Gatherer = require('../gatherer');
function patchDateNow() {
window.__stackTraceErrors = [];
// Override Date.now() so we know when if it's called.
const orig = Date.now;
const origDateNow = Date.now;
const originalPrepareStackTrace = Error.prepareStackTrace;
Date.now = function() {
try {
throw Error('__called Date.now()__');
} catch (e) {
if (e.stack) {
const split = e.stack.split('\n');
const m = split[split.length - 1].match(/(https?:\/\/.*):(\d+):(\d+)/);
if (m) {
window.__stackTraceErrors.push({url: m[1], line: m[2], col: m[3]});
}
}
}

return orig();
// See v8's Stack Trace API https://github.com/v8/v8/wiki/Stack-Trace-API#customizing-stack-traces
Error.prepareStackTrace = function(error, structStackTrace) {
const lastCallFrame = structStackTrace[structStackTrace.length - 1];
const file = lastCallFrame.getFileName();
const line = lastCallFrame.getLineNumber();
const col = lastCallFrame.getColumnNumber();
window.__stackTraceErrors.push({url: file, line, col});
return {url: file, line, col}; // return value populates e.stack.
};
Error.captureStackTrace(new Error('__called Date.now()__'));
// Remove custom formatter so future results use v8's formatter.
Error.prepareStackTrace = originalPrepareStackTrace;
return origDateNow();
};
}

Expand All @@ -58,8 +59,8 @@ class DateNowUse extends Gatherer {

afterPass(options) {
return options.driver.evaluateAsync(`(${collectDateNowUsage.toString()}())`)
.then(errors => {
this.artifact.errors = errors;
.then(dateNowUses => {
this.artifact.dateNowUses = dateNowUses;
}, _ => {
this.artifact = -1;
return;
Expand Down
35 changes: 25 additions & 10 deletions lighthouse-core/test/audits/dobetterweb/no-datenow-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,21 @@ describe('Page does not use Date.now()', () => {

it('passes when Date.now() is not used', () => {
const auditResult = DateNowUseAudit.audit({
DateNowUse: {errors: []},
DateNowUse: {dateNowUses: []},
URL: {finalUrl: URL},
});
assert.equal(auditResult.rawValue, true);
assert.equal(auditResult.extendedInfo.value.length, 0);
});

it('passes when Date.now() is used on a different origin', () => {
const auditResult = DateNowUseAudit.audit({
DateNowUse: {
dateNowUses: [
{url: 'http://different.com/two', line: 2, col: 2},
{url: 'http://example2.com/two', line: 2, col: 22}
]
},
URL: {finalUrl: URL},
});
assert.equal(auditResult.rawValue, true);
Expand All @@ -41,10 +55,10 @@ describe('Page does not use Date.now()', () => {
it('fails when Date.now() is used on the origin', () => {
const auditResult = DateNowUseAudit.audit({
DateNowUse: {
errors: [
{url: 'http://example.com/one', line: '1', col: '1'},
{url: 'http://example.com/two', line: '10', col: '1'},
{url: 'http://example2.com/two', line: '2', col: '2'}
dateNowUses: [
{url: 'http://example.com/one', line: 1, col: 1},
{url: 'http://example.com/two', line: 10, col: 1},
{url: 'http://example2.com/two', line: 2, col: 22}
]
},
URL: {finalUrl: URL},
Expand All @@ -53,16 +67,17 @@ describe('Page does not use Date.now()', () => {
assert.equal(auditResult.extendedInfo.value.length, 2);
});

it('passes when Date.now() is only used on a different origin', () => {
it('same file:line:col usage is deduped', () => {
const auditResult = DateNowUseAudit.audit({
DateNowUse: {
errors: [
{url: 'http://different.com/two', line: '2', col: '2'}
dateNowUses: [
{url: 'http://example.com/dupe', line: 1, col: 1},
{url: 'http://example.com/dupe', line: 1, col: 1}
]
},
URL: {finalUrl: URL},
});
assert.equal(auditResult.rawValue, true);
assert.equal(auditResult.extendedInfo.value.length, 0);
assert.equal(auditResult.rawValue, false);
assert.equal(auditResult.extendedInfo.value.length, 1);
});
});

0 comments on commit 62d8d96

Please sign in to comment.