38
loading...
This website collects cookies to deliver better user experience
npm install -g yo generator-code
yo code
// Your WebPageTest API key. REQUIRED
"wpt_extension.apiKey": "YOUR_API_KEY",
// The URL to test. If left out of settings.json, the extension will prompt you for a URL when run.
"wpt_extension.urlToTest": null,
// The location to test from. The location is comprised of the location of the testing agent, the browser to test on, and the connectivity in the following format: location:browser.connectivity.
"wpt_extension.location": "Dulles:Chrome.Cable",
// The number of tests to run
"wpt_extension.runs": 1,
// The interval (in seconds) to poll the API for test results
"wpt_extension.pollResults": 5,
// The maximum time (in seconds) to wait for test results
"wpt_extension.timeout": 240,
exports.getContentForTestSubmission = (url) =>{
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebPageTest Results</title>
<style>
h1 {text-align: center;}
h3 {text-align: center;}
</style>
</head>
<body>
<h1>WebPageTest Results</h1>
<h3>Test Submitted for <a href="${url}">${url}</a></h3>
<h3>Please wait until we fetch your results....</h3>
</body>
</html>`
}
exports.getContentForNoUrl = ()=>{
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebPageTest Results</title>
<style>
h1 {text-align: center;}
h3 {text-align: center;}
h4 {text-align: center;}
</style>
</head>
<body>
<h1>WebPageTest Results</h1>
<h3>Please enter a URL to test</h3>
<h4>You can add URL in settings.json file for vscode or enter it in the input field</h4>
</body>
</html>`
}
exports.getContentForError = (wptResponse)=>{
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebPageTest Results</title>
<style>
h1 {text-align: center;}
h3 {text-align: center;}
h4 {text-align: center;}
</style>
</head>
<body>
<h1>WebPageTest Results</h1>
<h3>${wptResponse.statusText}</h3>
</body>
</html>`
}
exports.getContentForChromeBasedSubmission = (wptResponse) =>{
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebPageTest Results</title>
<style>
//Lets see this later
</style>
</head>
<body>
<h1>WebPageTest Results</h1>
<h3>Test result for <a href="${wptResponse.result.data.url}">${wptResponse.result.data.url}</a></h3>
<h3>Find detailed results at <a href="${wptResponse.result.data.summary}">${wptResponse.result.data.summary}</a></h3>
<h4><b>From :</b> ${wptResponse.result.data.from} </h4>
<div>
<table>
<tbody>
<tr>
<th colspan="4" class="bordernone"></th>
<th colspan="3">Web Vitals</th>
<th colspan="3">Document Complete</th>
<th colspan="4">Fully Loaded</th>
</tr>
<tr>
<th>First Byte</th>
<th>Start Render</th>
<th>First Contentful Page</th>
<th>Speed Index</th>
<th>Largest Contentful Paint</th>
<th>Cumulative Layout Shift</th>
<th>Total Blocking Time</th>
<th>Time</th>
<th>Requests</th>
<th>Bytes In</th>
<th>Time</th>
<th>Requests</th>
<th>Bytes In</th>
</tr>
<tr>
<td>${wptResponse.result.data.median.firstView.TTFB/1000}s</th>
<td>${wptResponse.result.data.median.firstView.render/1000}s</th>
<td>${wptResponse.result.data.median.firstView.firstContentfulPaint/1000}s</th>
<td>${wptResponse.result.data.median.firstView.SpeedIndex/1000}s</th>
<td>${wptResponse.result.data.median.firstView.chromeUserTiming.LargestContentfulPaint/1000}s</td>
<td>${wptResponse.result.data.median.firstView.chromeUserTiming.CumulativeLayoutShift}</th>
<td>>= ${wptResponse.result.data.median.firstView.TotalBlockingTime/1000}s</th>
<td>${wptResponse.result.data.median.firstView.docTime/1000}s</th>
<td>${wptResponse.result.data.median.firstView.requestsDoc}</th>
<td>${Math.round(wptResponse.result.data.median.firstView.bytesInDoc/1024)}KB</th>
<td>${wptResponse.result.data.median.firstView.fullyLoaded/1000}s</th>
<td>${wptResponse.result.data.median.firstView.requestsFull}</th>
<td>${Math.round(wptResponse.result.data.median.firstView.bytesIn/1024)}KB</th>
</tr>
</tbody>
</table>
</div>
<div class="row" align="center">
<div class="column">
<h4>Waterfall</h4>
<img src="${wptResponse.result.data.median.firstView.images.waterfall}"/>
</div>
<div class="column">
<h4>Screenshot</h4>
<img src="${wptResponse.result.data.median.firstView.images.screenShot}"/>
</div>
</div>
</body>
</html>`;
}
exports.getContentForNonChromeBasedSubmission = (wptResponse) =>{
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebPageTest Results</title>
<style>
// Hang on, lets see this in a bit
</style>
</head>
<body>
<h1>WebPageTest Results</h1>
<h3>Test result for <a href="${wptResponse.result.data.url}">${wptResponse.result.data.url}</a></h3>
<h3>Find detailed results at <a href="${wptResponse.result.data.summary}">${wptResponse.result.data.summary}</a></h3>
<h4><b>From :</b> ${wptResponse.result.data.from} </h4>
<div>
<table>
<tbody>
<tr>
<th colspan="4" class="bordernone"></th>
<th colspan="1">Web Vitals</th>
<th colspan="3">Document Complete</th>
<th colspan="4">Fully Loaded</th>
</tr>
<tr>
<th>First Byte</th>
<th>Start Render</th>
<th>First Contentful Page</th>
<th>Speed Index</th>
<th>Total Blocking Time</th>
<th>Time</th>
<th>Requests</th>
<th>Bytes In</th>
<th>Time</th>
<th>Requests</th>
<th>Bytes In</th>
</tr>
<tr>
<td>${wptResponse.result.data.median.firstView.TTFB/1000}s</th>
<td>${wptResponse.result.data.median.firstView.render/1000}s</th>
<td>${wptResponse.result.data.median.firstView.firstContentfulPaint/1000}s</th>
<td>${wptResponse.result.data.median.firstView.SpeedIndex/1000}s</th>
<td>>= ${wptResponse.result.data.median.firstView.TotalBlockingTime/1000}s</th>
<td>${wptResponse.result.data.median.firstView.docTime/1000}s</th>
<td>${wptResponse.result.data.median.firstView.requestsDoc}</th>
<td>${Math.round(wptResponse.result.data.median.firstView.bytesInDoc/1024)}KB</th>
<td>${wptResponse.result.data.median.firstView.fullyLoaded/1000}s</th>
<td>${wptResponse.result.data.median.firstView.requestsFull}</th>
<td>${Math.round(wptResponse.result.data.median.firstView.bytesIn/1024)}KB</th>
</tr>
</tbody>
</table>
</div>
<div class="row" align="center">
<div class="column">
<h4>Waterfall</h4>
<img src="${wptResponse.result.data.median.firstView.images.waterfall}"/>
</div>
<div class="column">
<h4>Screenshot</h4>
<img src="${wptResponse.result.data.median.firstView.images.screenShot}"/>
</div>
</div>
</body>
</html>`;
}
<style>
h1 {text-align: center;}
h2 {text-align: center;}
.row {
display: flex;
}
.column {
flex: 33.33%;
padding: 5px;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid silver;
padding: 8px;
text-align: center;
}
.bordernone{
border: none;
}
</style>
exports.runTest = (wpt, url, options) => {
const tempOptions = JSON.parse(JSON.stringify(options));
return new Promise((resolve, reject) => {
wpt.runTest(url, tempOptions, async(err, result) => {
try {
if (result) {
return resolve({'result':result,'err':err});
} else {
return reject(err);
}
} catch (e) {
console.info(e);
}
})
});
}
const vscode = require('vscode'); //line #1
const WebPageTest = require("webpagetest"); //line #2
const wptHelpers = require('./wpt-helpers'); //line #3
const webViews = require('./utils/web-views'); //line #4
let options = {
"firstViewOnly": true,
"runs": 1,
"location": 'Dulles:Chrome.Cable',
"pollResults": 5,
"timeout": 240
}
/**
* @param {vscode.ExtensionContext} context
*/
async function activate(context) {
let disposable = vscode.commands.registerCommand('webpagetest.wpt', async function () { //line #18
try {
const wpt_extension_config = JSON.parse(JSON.stringify(vscode.workspace.getConfiguration('wpt_extension'))) //line #22
const WPT_API_KEY = wpt_extension_config.apiKey;
const wpt = new WebPageTest('www.webpagetest.org', WPT_API_KEY); //line #24
let url = wpt_extension_config['urlToTest'];
if (!url)
url = await vscode.window.showInputBox({"prompt": "Enter the URL you want to test."}) //line #27
wpt_extension_config['firstViewOnly'] = wpt_extension_config['firstViewOnly'] === false ? false : options['firstViewOnly']; //line #29
wpt_extension_config['location'] = wpt_extension_config['location'] || options['location'];
wpt_extension_config['pollResults'] = wpt_extension_config['pollResults'] || options['pollResults'];
wpt_extension_config['timeout'] = wpt_extension_config['timeout'] || options['timeout'];
wpt_extension_config['runs'] = wpt_extension_config['runs'] || options['runs']; //line #33
var panel = vscode.window.createWebviewPanel(
'webpagetest',
'WebPageTest',
vscode.ViewColumn.One
);
if (!url) {
panel.webview.html = webViews.getContentForNoUrl();
return;
}
var panel = vscode.window.createWebviewPanel( //line #1
'webpagetest',
'WebPageTest',
vscode.ViewColumn.One
);
if (!url) {
panel.webview.html = webViews.getContentForNoUrl(); //line #8
return;
}
panel.webview.html = webViews.getContentForTestSubmission(url);
const wptResponse = await wptHelpers.runTest(wpt, url.toString(), wpt_extension_config);
const chromeUserTiming = wptResponse.result.data.median.firstView.chromeUserTiming;
if (chromeUserTiming) {
for (let i = 0; i < chromeUserTiming.length; i++) {
if (chromeUserTiming[i].name == 'firstContentfulPaint')
wptResponse.result.data.median.firstView.firstContentfulPaint = chromeUserTiming[i].time;
if (chromeUserTiming[i].name == 'LargestContentfulPaint')
wptResponse.result.data.median.firstView.chromeUserTiming.LargestContentfulPaint = chromeUserTiming[i].time;
if (chromeUserTiming[i].name == 'CumulativeLayoutShift')
wptResponse.result.data.median.firstView.chromeUserTiming.CumulativeLayoutShift = chromeUserTiming[i].value.toFixed(3);
}
panel.webview.html = webViews.getContentForChromeBasedSubmission(wptResponse); //line #24
}
else {
panel.webview.html = webViews.getContentForNonChromeBasedSubmission(wptResponse); //line #27
}