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

viewer: add option for loading from the PSI API #9546

Merged
merged 54 commits into from
Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
59fe77e
merge viewer changes
connorjclark Aug 9, 2019
62cc1b1
categories query param
connorjclark Aug 9, 2019
02a4800
viewer: psi api
connorjclark Aug 9, 2019
47227d8
undo accidental changes to drop test
connorjclark Aug 9, 2019
2fa37c9
lock
connorjclark Aug 9, 2019
4c33bb6
redo lock
connorjclark Aug 9, 2019
2e8fbee
psi-api.js, ?category
connorjclark Aug 9, 2019
621ede6
allow gist
connorjclark Aug 9, 2019
c0513b3
fix logic
connorjclark Aug 9, 2019
4e911d0
make tests less of a joke
connorjclark Aug 9, 2019
70a3b23
array param setting for query
connorjclark Aug 9, 2019
550a0ea
use all psi api
connorjclark Aug 9, 2019
01af9cb
rename
connorjclark Aug 9, 2019
04ed696
readme
connorjclark Aug 9, 2019
a680af4
psi errors
connorjclark Aug 12, 2019
56840af
Merge remote-tracking branch 'origin/master' into viewer-psi
connorjclark Aug 12, 2019
fcf914b
Merge remote-tracking branch 'origin/master' into viewer-psi
connorjclark Aug 13, 2019
3ec6127
readme
connorjclark Aug 13, 2019
e3d212f
load from deep link
connorjclark Aug 13, 2019
6934f19
comment
connorjclark Aug 13, 2019
552b03f
test url doesnt change
connorjclark Aug 13, 2019
4fef787
put that code back
connorjclark Aug 13, 2019
6ca5ad0
cat test meoooow
connorjclark Aug 13, 2019
82ad774
for of
connorjclark Aug 13, 2019
943df67
fetch psi refactor
connorjclark Aug 13, 2019
67b5180
name
connorjclark Aug 13, 2019
2de9b62
provider
connorjclark Aug 13, 2019
97ddc98
use logger
connorjclark Aug 13, 2019
143f3bd
provider param
connorjclark Aug 14, 2019
fc91765
Merge remote-tracking branch 'origin/master' into viewer-psi
connorjclark Aug 15, 2019
8cab861
defer main
connorjclark Aug 15, 2019
547549f
readme
connorjclark Aug 15, 2019
48f9e46
source
connorjclark Aug 15, 2019
69f3dd2
for
connorjclark Aug 15, 2019
c104604
load blur for gist too
connorjclark Aug 15, 2019
fb8f814
psiurl
connorjclark Aug 15, 2019
fd05a06
remove extra blue. rename to fetchFromPSI
connorjclark Aug 16, 2019
e849af1
Update lighthouse-viewer/app/src/main.js
connorjclark Aug 16, 2019
0c8bb28
paul promise refactor. eslint ignore.
connorjclark Aug 16, 2019
04f4e6b
better main init
connorjclark Aug 16, 2019
6185a8a
eslint
connorjclark Aug 16, 2019
3b12386
booleans
connorjclark Aug 20, 2019
7d23359
comment
connorjclark Aug 20, 2019
bbd7396
restore
connorjclark Aug 20, 2019
a120dd1
readme, promise ret
connorjclark Aug 20, 2019
0fcc878
Merge branch 'viewer-psi' of github.com:GoogleChrome/lighthouse into …
connorjclark Aug 20, 2019
6fae521
refactor interception in test
connorjclark Aug 20, 2019
18c74cf
test error
connorjclark Aug 20, 2019
80ec9ca
move default cat test
connorjclark Aug 20, 2019
80f895c
rm extra
connorjclark Aug 20, 2019
ceb95fc
types and teests
connorjclark Aug 20, 2019
8369d85
test more params
connorjclark Aug 20, 2019
4b6ade7
last changes
connorjclark Aug 21, 2019
1469211
params
connorjclark Aug 21, 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
80 changes: 71 additions & 9 deletions lighthouse-viewer/app/src/lighthouse-report-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,42 @@ function find(query, context) {
return result;
}

/** @typedef {{lighthouseResult: LH.Result}} PSIResponse */

const PSI_KEY = 'AIzaSyAjcDRNN9CX9dCazhqI4lGR7yyQbkd_oYE';
const PSI_DEFAULT_CATEGORIES = [
'performance',
'accessibility',
'seo',
'best-practices',
'pwa',
];

/**
* @param {string} url
* @param {string[]} categories
* @return {Promise<PSIResponse>}
*/
function callPSI(url, categories) {
const psiUrl = new URL('https://www.googleapis.com/pagespeedonline/v5/runPagespeed');
/** @type {Record<string, string | string[]>} */
const params = {
key: PSI_KEY,
url,
category: categories,
strategy: 'mobile',
utm_source: 'Lighthouse Chrome Extension',
};
Object.entries(params).forEach(([key, value]) => {
const values = Array.isArray(value) ? value : [value];
for (const singleValue of values) {
psiUrl.searchParams.append(key, singleValue);
}
});

return fetch(psiUrl.href).then(res => res.json());
}

/**
* Class that manages viewing Lighthouse reports.
*/
Expand All @@ -42,9 +78,19 @@ class LighthouseReportViewer {
*/
this._reportIsFromGist = false;

this._addEventListeners();
this._loadFromDeepLink();
this._listenForMessages();
this._reportIsFromPSI = false;

const params = new URLSearchParams(location.search);
const url = params.get('url');
if (url) {
const categoriesCsv = params.get('categories');
const categories = categoriesCsv ? categoriesCsv.split(',') : PSI_DEFAULT_CATEGORIES;
this._loadFromPSI(url, categories);
} else {
this._addEventListeners();
this._loadFromDeepLink();
this._listenForMessages();
}
}

static get APP_URL() {
Expand Down Expand Up @@ -159,9 +205,9 @@ class LighthouseReportViewer {
renderer.renderReport(json, container);

// Only give gist-saving callback (and clear gist from query string) if
// current report isn't from a gist.
// current report isn't from a gist or PSI.
let saveCallback = null;
if (!this._reportIsFromGist) {
if (!this._reportIsFromGist && !this._reportIsFromPSI) {
saveCallback = this._onSaveJson;
history.pushState({}, '', LighthouseReportViewer.APP_URL);
}
Expand Down Expand Up @@ -202,7 +248,7 @@ class LighthouseReportViewer {
} catch (e) {
throw new Error('Could not parse JSON file.');
}
this._reportIsFromGist = false;
this._reportIsFromGist = this._reportIsFromPSI = false;
this._replaceReportHtml(json);
}).catch(err => logger.error(err.message));
}
Expand Down Expand Up @@ -276,7 +322,6 @@ class LighthouseReportViewer {
* @private
*/
_onPaste(e) {
if (!e.clipboardData) return;
e.preventDefault();

// Try paste as gist URL.
Expand All @@ -294,7 +339,7 @@ class LighthouseReportViewer {
// Try paste as json content.
try {
const json = JSON.parse(e.clipboardData.getData('text'));
this._reportIsFromGist = false;
this._reportIsFromGist = this._reportIsFromPSI = false;
this._replaceReportHtml(json);

if (window.ga) {
Expand Down Expand Up @@ -358,7 +403,7 @@ class LighthouseReportViewer {
_listenForMessages() {
window.addEventListener('message', e => {
if (e.source === self.opener && e.data.lhresults) {
this._reportIsFromGist = false;
this._reportIsFromGist = this._reportIsFromPSI = false;
this._replaceReportHtml(e.data.lhresults);

if (self.opener && !self.opener.closed) {
Expand All @@ -375,6 +420,23 @@ class LighthouseReportViewer {
self.opener.postMessage({opened: true}, '*');
}
}

/**
* @param {string} url
* @param {string[]} categories
*/
_loadFromPSI(url, categories) {
const loadingOverlayEl = document.createElement('div');
loadingOverlayEl.classList.add('lh-loading-overlay');
loadingOverlayEl.textContent = 'Waiting for Lighthouse results ...';
find('.viewer-placeholder-inner', document.body).classList.add('lh-loading');
document.body.appendChild(loadingOverlayEl);
callPSI(url, categories).then(psiResponse => {
this._reportIsFromPSI = true;
loadingOverlayEl.remove();
this._replaceReportHtml(psiResponse.lighthouseResult);
});
}
}

// node export for testing.
Expand Down
12 changes: 12 additions & 0 deletions lighthouse-viewer/app/styles/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,15 @@
.lh-tools__dropdown .lh-tools--gist {
display: block !important;
}

.lh-loading-overlay {
position: absolute;
top: 50%;
transform: translateX(-50%);
left: 50%;
filter: none;
}

.lh-loading {
filter: blur(2px);
}
67 changes: 21 additions & 46 deletions lighthouse-viewer/test/drag-and-drop-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

/* eslint-env jest */

const assert = require('assert');

const testHelpers = require('./test-helpers.js');

// Called before other src import so code that relies on `document` and
Expand All @@ -15,6 +17,10 @@ testHelpers.setupJsDomGlobals();

const DragAndDrop = require('../app/src/drag-and-drop.js');

function assertUIReset() {
assert.ok(!document.querySelector('.drop_zone').classList.contains('dropping'));
}

describe('DragAndDrop', () => {
beforeEach(function() {
// Reconstruct page on every test so event listeners are clean.
Expand All @@ -23,62 +29,31 @@ describe('DragAndDrop', () => {

afterEach(testHelpers.cleanupJsDomGlobals);

it('document responds to drop event with file', () => {
const mockCallback = jest.fn();
new DragAndDrop(mockCallback);

// create custom drop event with mock files in dataTransfer
const event = new window.CustomEvent('drop');
event.dataTransfer = {
files: ['mock file'],
// TODO: test drop event on document. Callback is not getting called
// because jsdom doesn't support clipboard API: https://github.com/tmpvar/jsdom/issues/1568/.
it.skip('document responds to drag and drop events', done => {
const callback = _ => {
assert.ok(true, 'file change callback is called after drop event');
done();
};
document.dispatchEvent(event);
expect(mockCallback).toBeCalledWith('mock file');
});

it('document ignores drop event without file', () => {
const mockCallback = jest.fn();
new DragAndDrop(mockCallback);
new DragAndDrop(callback);

document.dispatchEvent(new window.CustomEvent('drop'));
expect(mockCallback).not.toBeCalled();
});

it('document responds to dragover event with file', () => {
const mockCallback = jest.fn();
new DragAndDrop(mockCallback);

const event = new window.CustomEvent('dragover');
event.dataTransfer = {
files: ['mock file'],
};
document.dispatchEvent(event);
expect(event.dataTransfer.dropEffect).toEqual('copy');
});

it('document ignores dragover event without file', () => {
const mockCallback = jest.fn();
new DragAndDrop(mockCallback);

const event = new window.CustomEvent('dragover');
document.dispatchEvent(event);
expect(event.dataTransfer).toBeUndefined();
});

it('document responds to mouseleave event when not dragging', () => {
new DragAndDrop(jest.fn);
it('document responds to drag and drop events', () => {
// eslint-disable-next-line no-unused-vars
const dragAndDrop = new DragAndDrop();

document.dispatchEvent(new window.CustomEvent('mouseleave'));
expect(document.querySelector('.drop_zone').classList.contains('dropping')).toBeFalsy();
});

it('document responds to mouseleave and dragenter events', () => {
new DragAndDrop(jest.fn);
assertUIReset();

document.dispatchEvent(new window.CustomEvent('dragenter'));
expect(document.querySelector('.drop_zone').classList.contains('dropping')).toBeTruthy();
assert.ok(document.querySelector('.drop_zone').classList.contains('dropping'));

document.dispatchEvent(new window.CustomEvent('mouseleave'));
expect(document.querySelector('.drop_zone').classList.contains('dropping')).toBeFalsy();
// TODO: see note above about drop event testing.
// document.dispatchEvent(new window.CustomEvent('drop'));
// assertUIReset();
});
});
Loading