-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
extension(tests): Add extension smoketest #4640
Changes from 18 commits
133e73a
32160e8
e166719
9f4a831
0f70cc6
e4c6878
1b39ac5
48dd147
df52a55
51c1bdf
67f0b3f
69747ea
4ebeefe
2096afb
644df57
5f10d57
0722566
c3ce3f9
ff432b0
a29d829
d1b6baa
4f1e160
c8ecaf9
6409d26
198d47f
e20717c
259441f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/** | ||
* @license Copyright 2018 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'; | ||
|
||
/* eslint-env mocha */ | ||
|
||
const path = require('path'); | ||
const assert = require('assert'); | ||
const fs = require('fs'); | ||
const puppeteer = require('../../node_modules/puppeteer/index.js'); | ||
|
||
const lighthouseExtensionPath = path.resolve(__dirname, '../app'); | ||
const config = require(path.resolve(__dirname, '../../lighthouse-core/config/default.js')); | ||
|
||
const getAuditsOfCategory = category => config.categories[category].audits; | ||
|
||
describe('Lighthouse chrome extension', function() { | ||
const manifestLocation = path.join(lighthouseExtensionPath, 'manifest.json'); | ||
const lighthouseCategories = Object.keys(config.categories); | ||
let browser; | ||
let extensionPage; | ||
let originalManifest; | ||
|
||
function getAuditElementsCount({category, selector}) { | ||
return extensionPage.evaluate(({category, selector}) => | ||
document.querySelector(`#${category}`).parentNode.querySelectorAll(selector).length, | ||
{category, selector} | ||
); | ||
} | ||
|
||
before(async function() { | ||
// eslint-disable-next-line | ||
this.timeout(90 * 1000); | ||
|
||
// read original manifest | ||
originalManifest = fs.readFileSync(manifestLocation); | ||
|
||
const manifest = JSON.parse(originalManifest); | ||
// add tabs permision to the manifest | ||
manifest.permissions.push('tabs'); | ||
// write new file to document | ||
fs.writeFileSync(manifestLocation, JSON.stringify(manifest, null, 2)); | ||
|
||
// start puppeteer | ||
browser = await puppeteer.launch({ | ||
headless: false, | ||
executablePath: process.env.CHROME_PATH, | ||
args: [ | ||
`--disable-extensions-except=${lighthouseExtensionPath}`, | ||
`--load-extension=${lighthouseExtensionPath}`, | ||
], | ||
}); | ||
|
||
const page = await browser.newPage(); | ||
await page.goto('https://www.paulirish.com', {waitUntil: 'networkidle2'}); | ||
const targets = await browser.targets(); | ||
const extensionTarget = targets.find(({_targetInfo}) => { | ||
return _targetInfo.title === 'Lighthouse' && | ||
_targetInfo.type === 'background_page'; | ||
}); | ||
|
||
if (!extensionTarget) { | ||
return await browser.close(); | ||
} | ||
|
||
const client = await extensionTarget.createCDPSession(); | ||
const lighthouseResult = await client.send( | ||
'Runtime.evaluate', | ||
{ | ||
expression: `runLighthouseInExtension({ | ||
restoreCleanState: true, | ||
}, ${JSON.stringify(lighthouseCategories)})`, | ||
awaitPromise: true, | ||
returnByValue: true, | ||
} | ||
); | ||
|
||
if (lighthouseResult.exceptionDetails) { | ||
if (lighthouseResult.exceptionDetails.exception) { | ||
throw new Error(lighthouseResult.exceptionDetails.exception.description); | ||
} | ||
|
||
throw new Error(lighthouseResult.exceptionDetails.text); | ||
} | ||
|
||
extensionPage = (await browser.pages()) | ||
.find(page => page.url().includes('blob:chrome-extension://')); | ||
}); | ||
|
||
after(async () => { | ||
// put the default manifest back | ||
fs.writeFileSync(manifestLocation, originalManifest); | ||
|
||
if (browser) { | ||
await browser.close(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the test throws, do we want this pulled out into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we could also to the lighthouse run in before and do regular test cases
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 let's do that! |
||
} | ||
}); | ||
|
||
it('should contain all categories', async () => { | ||
const categories = await extensionPage.$$(`#${lighthouseCategories.join(',#')}`); | ||
assert.equal(categories.length, lighthouseCategories.length, | ||
`${categories.join(' ')} does not match ${lighthouseCategories.join(' ')}`); | ||
}); | ||
|
||
it('should contain audits of all categories', async () => { | ||
for (const category of lighthouseCategories) { | ||
let selector = '.lh-audit'; | ||
let expected = getAuditsOfCategory(category).length; | ||
if (category === 'performance') { | ||
selector = '.lh-audit,.lh-timeline-metric,.lh-perf-hint'; | ||
expected = getAuditsOfCategory(category).filter(a => !!a.group).length; | ||
} | ||
|
||
const elementCount = await getAuditElementsCount({category, selector}); | ||
|
||
assert.equal(expected, elementCount, | ||
`${category} does not have the correct amount of audits`); | ||
} | ||
}); | ||
|
||
it('should contain a filmstrip', async () => { | ||
const filmstrip = await extensionPage.$('.lh-filmstrip'); | ||
|
||
assert.ok(!!filmstrip, `filmstrip is not available`); | ||
}); | ||
|
||
it('should not have any audit errors', async () => { | ||
function getDebugStrings(elems) { | ||
return elems.map(el => ({ | ||
debugString: el.textContent, | ||
title: el.closest('.lh-audit').querySelector('.lh-score__title').textContent, | ||
})); | ||
} | ||
|
||
const auditErrors = await extensionPage.$$eval('.lh-debug', getDebugStrings); | ||
const errors = auditErrors.filter(item => item.debugString.includes('Audit error:')); | ||
assert.deepStrictEqual(errors, [], 'Audit errors found within the report'); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you skip the pptr chromium download, is this at least chrome 66. PPTR may need that version to work properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just thought it was a bit stupid to install it twice and we moved to chrome stable to test the lowest version we support. I could enable chromium again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, it does appear to work fine with chrome stable.
I'm also fine with using the bundled Chromium, but yes it does seem wasteful to d/l each time.
If it works fine with chrome stable as of now, then moving forward (assuming we infrequently bump the pptr version), it shouldn't regress. So I'm +1 to using the stable.