lighthouse 9.5.0-dev.20230126 → 9.5.0-dev.20230128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/config/metrics-to-audits.js +1 -0
- package/dist/report/bundle.esm.js +112 -21
- package/dist/report/flow.js +13 -13
- package/dist/report/standalone.js +5 -5
- package/package.json +1 -1
- package/report/renderer/details-renderer.js +15 -2
- package/report/renderer/report-ui-features.js +25 -19
- package/report/renderer/report-utils.d.ts +13 -0
- package/report/renderer/report-utils.js +72 -0
- package/report/test/renderer/report-ui-features-test.js +299 -72
- package/report/test/renderer/report-utils-test.js +51 -0
|
@@ -103,19 +103,29 @@ describe('ReportUIFeatures', () => {
|
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
describe('third-party filtering', () => {
|
|
106
|
-
let
|
|
106
|
+
let lhrJson;
|
|
107
107
|
|
|
108
108
|
before(() => {
|
|
109
109
|
const lhr = JSON.parse(JSON.stringify(sampleResults));
|
|
110
110
|
lhr.requestedUrl = lhr.finalDisplayedUrl = 'http://www.example.com';
|
|
111
|
+
|
|
111
112
|
const webpAuditItemTemplate = {
|
|
112
113
|
...sampleResults.audits['modern-image-formats'].details.items[0],
|
|
113
114
|
wastedBytes: 8.8 * 1024,
|
|
115
|
+
entity: undefined, // Remove entity classification from previous result.
|
|
116
|
+
};
|
|
117
|
+
const renderBlockingAuditItemTemplate = {
|
|
118
|
+
...sampleResults.audits['render-blocking-resources'].details.items[0],
|
|
119
|
+
entity: undefined, // Remove entity classification from previous result.
|
|
120
|
+
};
|
|
121
|
+
const textCompressionAuditItemTemplate = {
|
|
122
|
+
...sampleResults.audits['uses-text-compression'].details.items[0],
|
|
123
|
+
entity: undefined, // Remove entity classification from previous result.
|
|
124
|
+
};
|
|
125
|
+
const bootupTimeAuditItemTemplate = {
|
|
126
|
+
...sampleResults.audits['bootup-time'].details.items[0],
|
|
127
|
+
entity: undefined, // Remove entity classification from previous result.
|
|
114
128
|
};
|
|
115
|
-
const renderBlockingAuditItemTemplate =
|
|
116
|
-
sampleResults.audits['render-blocking-resources'].details.items[0];
|
|
117
|
-
const textCompressionAuditItemTemplate =
|
|
118
|
-
sampleResults.audits['uses-text-compression'].details.items[0];
|
|
119
129
|
|
|
120
130
|
// Interleave first/third party URLs to test restoring order.
|
|
121
131
|
lhr.audits['modern-image-formats'].details.items = [
|
|
@@ -202,79 +212,296 @@ describe('ReportUIFeatures', () => {
|
|
|
202
212
|
},
|
|
203
213
|
];
|
|
204
214
|
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('filters out sub-item rows of third party resources on click', () => {
|
|
226
|
-
dom.find('#unused-javascript', container);
|
|
227
|
-
const filterCheckbox = dom.find('#unused-javascript .lh-3p-filter-input', container);
|
|
228
|
-
|
|
229
|
-
function getRowIdentifiers() {
|
|
230
|
-
return dom
|
|
231
|
-
.findAll(
|
|
232
|
-
'#unused-javascript tbody tr:not(.lh-row--hidden)', container)
|
|
233
|
-
.map(el => el.textContent);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const initialExpected = [
|
|
237
|
-
'/script1.js(www.cdn.com)24.0 KiB8.8 KiB',
|
|
238
|
-
'10.0 KiB0.0 KiB',
|
|
239
|
-
'20.0 KiB0.0 KiB',
|
|
240
|
-
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
241
|
-
'30.0 KiB0.0 KiB',
|
|
242
|
-
'40.0 KiB0.0 KiB',
|
|
243
|
-
'/script3.js(www.notexample.com)24.0 KiB8.8 KiB',
|
|
244
|
-
'50.0 KiB0.0 KiB',
|
|
245
|
-
'60.0 KiB0.0 KiB',
|
|
215
|
+
// A mix of 3P, 1P and Unattributable.
|
|
216
|
+
lhr.audits['bootup-time'].details.items = [
|
|
217
|
+
{
|
|
218
|
+
...bootupTimeAuditItemTemplate,
|
|
219
|
+
url: 'http://www.example.com/dobetterweb/dbw_tester.html',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
...bootupTimeAuditItemTemplate,
|
|
223
|
+
url: 'Unattributable',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
...bootupTimeAuditItemTemplate,
|
|
227
|
+
url: 'http://www.example.com/dobetterweb/third_party/aggressive-promise-polyfill.js',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
...bootupTimeAuditItemTemplate,
|
|
231
|
+
url: 'http://www.cdn.com/script1.js',
|
|
232
|
+
},
|
|
246
233
|
];
|
|
247
234
|
|
|
248
|
-
|
|
249
|
-
filterCheckbox.click();
|
|
250
|
-
expect(getRowIdentifiers()).toEqual([
|
|
251
|
-
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
252
|
-
'30.0 KiB0.0 KiB',
|
|
253
|
-
'40.0 KiB0.0 KiB',
|
|
254
|
-
]);
|
|
255
|
-
filterCheckbox.click();
|
|
256
|
-
expect(getRowIdentifiers()).toEqual(initialExpected);
|
|
235
|
+
lhrJson = lhr;
|
|
257
236
|
});
|
|
258
237
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
238
|
+
describe('entity-classification based filtering works', () => {
|
|
239
|
+
let container;
|
|
240
|
+
|
|
241
|
+
before(() => {
|
|
242
|
+
// Setup entity-classification with recognized entities first.
|
|
243
|
+
lhrJson.entities = {
|
|
244
|
+
firstParty: 'example.com',
|
|
245
|
+
list: [
|
|
246
|
+
{
|
|
247
|
+
name: 'example.com',
|
|
248
|
+
isFirstParty: true,
|
|
249
|
+
isUnrecognized: true,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: 'cdn.com',
|
|
253
|
+
isUnrecognized: true,
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: 'notexample.com',
|
|
257
|
+
isUnrecognized: true,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
name: 'google.com',
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
entityIndexByOrigin: {
|
|
264
|
+
'http://www.example.com': 0,
|
|
265
|
+
'http://www.cdn.com': 1,
|
|
266
|
+
'http://www.notexample.com': 2,
|
|
267
|
+
'http://www.google.com': 3,
|
|
268
|
+
},
|
|
269
|
+
entityIndexByName: {
|
|
270
|
+
'example.com': 0,
|
|
271
|
+
'cdn.com': 1,
|
|
272
|
+
'notexample.com': 2,
|
|
273
|
+
'google.com': 3,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Entity resolution is done during prepareReportResult
|
|
278
|
+
const result = ReportUtils.prepareReportResult(lhrJson);
|
|
279
|
+
|
|
280
|
+
// render a report onto the UIFeature dom
|
|
281
|
+
container = render(result);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('all items that contain a url have been marked with an entity for filtering', () => {
|
|
285
|
+
['modern-image-formats', 'render-blocking-resources', 'unused-javascript',
|
|
286
|
+
'uses-text-compression'].forEach(audit => {
|
|
287
|
+
dom.findAll(`#${audit} tr`, container)
|
|
288
|
+
.filter(el => dom.findAll('.lh-text__url', el).length > 0)
|
|
289
|
+
.forEach(el => expect(el.dataset.entity).toBeTruthy());
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('filters out third party resources in on click', () => {
|
|
294
|
+
const filterCheckbox = dom.find('#modern-image-formats .lh-3p-filter-input', container);
|
|
295
|
+
|
|
296
|
+
function getUrlsInTable() {
|
|
297
|
+
return dom
|
|
298
|
+
.findAll('#modern-image-formats tr:not(.lh-row--hidden) .lh-text__url a:first-child', container) // eslint-disable-line max-len
|
|
299
|
+
.map(el => el.textContent);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
expect(getUrlsInTable()).toEqual(['/img1.jpg', '/img2.jpg', '/img3.jpg']);
|
|
303
|
+
filterCheckbox.click();
|
|
304
|
+
expect(getUrlsInTable()).toEqual(['/img2.jpg']);
|
|
305
|
+
filterCheckbox.click();
|
|
306
|
+
expect(getUrlsInTable()).toEqual(['/img1.jpg', '/img2.jpg', '/img3.jpg']);
|
|
307
|
+
|
|
308
|
+
const filter3pCount = dom.find('#modern-image-formats .lh-3p-filter-count', container);
|
|
309
|
+
expect(filter3pCount.textContent).toEqual('2');
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('filters out sub-item rows of third party resources on click', () => {
|
|
313
|
+
dom.find('#unused-javascript', container);
|
|
314
|
+
const filterCheckbox = dom.find('#unused-javascript .lh-3p-filter-input', container);
|
|
315
|
+
|
|
316
|
+
function getRowIdentifiers() {
|
|
317
|
+
return dom
|
|
318
|
+
.findAll(
|
|
319
|
+
'#unused-javascript tbody tr:not(.lh-row--hidden)', container)
|
|
320
|
+
.map(el => el.textContent);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const initialExpected = [
|
|
324
|
+
'/script1.js(www.cdn.com)24.0 KiB8.8 KiB',
|
|
325
|
+
'10.0 KiB0.0 KiB',
|
|
326
|
+
'20.0 KiB0.0 KiB',
|
|
327
|
+
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
328
|
+
'30.0 KiB0.0 KiB',
|
|
329
|
+
'40.0 KiB0.0 KiB',
|
|
330
|
+
'/script3.js(www.notexample.com)24.0 KiB8.8 KiB',
|
|
331
|
+
'50.0 KiB0.0 KiB',
|
|
332
|
+
'60.0 KiB0.0 KiB',
|
|
333
|
+
];
|
|
334
|
+
|
|
335
|
+
expect(getRowIdentifiers()).toEqual(initialExpected);
|
|
336
|
+
filterCheckbox.click();
|
|
337
|
+
expect(getRowIdentifiers()).toEqual([
|
|
338
|
+
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
339
|
+
'30.0 KiB0.0 KiB',
|
|
340
|
+
'40.0 KiB0.0 KiB',
|
|
341
|
+
]);
|
|
342
|
+
filterCheckbox.click();
|
|
343
|
+
expect(getRowIdentifiers()).toEqual(initialExpected);
|
|
344
|
+
|
|
345
|
+
const filter3pCount = dom.find('#unused-javascript .lh-3p-filter-count', container);
|
|
346
|
+
expect(filter3pCount.textContent).toEqual('2');
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it('adds no filter for audits in thirdPartyFilterAuditExclusions', () => {
|
|
350
|
+
const checkboxClassName = 'lh-3p-filter-input';
|
|
351
|
+
|
|
352
|
+
const yesCheckbox = dom.find(`#modern-image-formats .${checkboxClassName}`, container);
|
|
353
|
+
expect(yesCheckbox).toBeTruthy();
|
|
354
|
+
|
|
355
|
+
expect(() => dom.find(`#uses-rel-preconnect .${checkboxClassName}`, container))
|
|
356
|
+
.toThrowError('query #uses-rel-preconnect .lh-3p-filter-input not found');
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it('treats non-classifiable url values as first-party', () => {
|
|
360
|
+
const auditEl = dom.find('#bootup-time', container);
|
|
361
|
+
const filterCheckboxEl = dom.find('.lh-3p-filter-input', auditEl);
|
|
362
|
+
|
|
363
|
+
// Ensure 3p filter is visible.
|
|
364
|
+
expect(dom.find('.lh-3p-filter', auditEl).hidden).toBeFalsy();
|
|
365
|
+
|
|
366
|
+
function getUrlsInTable() {
|
|
367
|
+
return dom.findAll('tbody tr:not(.lh-row--hidden) td:first-child', auditEl)
|
|
368
|
+
.map(el => el.textContent);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
const preFilterRowSet = [
|
|
372
|
+
'/dobetterweb/dbw_tester.html(www.example.com)',
|
|
373
|
+
'Unattributable',
|
|
374
|
+
'…third_party/aggressive-promise-polyfill.js(www.example.com)',
|
|
375
|
+
'/script1.js(www.cdn.com)',
|
|
376
|
+
];
|
|
377
|
+
|
|
378
|
+
expect(getUrlsInTable()).toEqual(preFilterRowSet);
|
|
379
|
+
filterCheckboxEl.click();
|
|
380
|
+
expect(getUrlsInTable()).toEqual(preFilterRowSet.filter(
|
|
381
|
+
text => !text.includes('cdn.com')));
|
|
382
|
+
filterCheckboxEl.click();
|
|
383
|
+
expect(getUrlsInTable()).toEqual(preFilterRowSet);
|
|
384
|
+
|
|
385
|
+
const filter3pCountEl = dom.find('.lh-3p-filter-count', auditEl);
|
|
386
|
+
expect(filter3pCountEl.textContent).toEqual('1');
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it('filter is hidden when just third party resources', () => {
|
|
390
|
+
const filterControl =
|
|
391
|
+
dom.find('#render-blocking-resources .lh-3p-filter', container);
|
|
392
|
+
expect(filterControl.hidden).toEqual(true);
|
|
393
|
+
// Expect the hidden filter to still count third parties correctly.
|
|
394
|
+
const filter3pCount = dom.find('#render-blocking-resources .lh-3p-filter-count',
|
|
395
|
+
container);
|
|
396
|
+
expect(filter3pCount.textContent).toEqual('3');
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it('filter is hidden for just first party resources', () => {
|
|
400
|
+
const filterControl = dom.find('#uses-text-compression .lh-3p-filter', container);
|
|
401
|
+
expect(filterControl.hidden).toEqual(true);
|
|
402
|
+
// Expect the hidden filter to still count third parties correctly.
|
|
403
|
+
const filter3pCount = dom.find('#uses-text-compression .lh-3p-filter-count', container);
|
|
404
|
+
expect(filter3pCount.textContent).toEqual('0');
|
|
405
|
+
});
|
|
273
406
|
});
|
|
274
407
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
408
|
+
describe('legacy third-party filtering continues to work', () => {
|
|
409
|
+
let container;
|
|
410
|
+
|
|
411
|
+
before(() => {
|
|
412
|
+
// Remove entity-classification audit to fall back to origin string match
|
|
413
|
+
// based third-party filtering (legacy)
|
|
414
|
+
delete lhrJson.entities;
|
|
415
|
+
|
|
416
|
+
const result = ReportUtils.prepareReportResult(lhrJson);
|
|
417
|
+
|
|
418
|
+
// render a report onto the UIFeature dom
|
|
419
|
+
container = render(result);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('filters out third party resources in on click', () => {
|
|
423
|
+
const filterCheckbox = dom.find('#modern-image-formats .lh-3p-filter-input', container);
|
|
424
|
+
|
|
425
|
+
function getUrlsInTable() {
|
|
426
|
+
return dom
|
|
427
|
+
.findAll('#modern-image-formats tr:not(.lh-row--hidden) .lh-text__url a:first-child', container) // eslint-disable-line max-len
|
|
428
|
+
.map(el => el.textContent);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
expect(getUrlsInTable()).toEqual(['/img1.jpg', '/img2.jpg', '/img3.jpg']);
|
|
432
|
+
filterCheckbox.click();
|
|
433
|
+
expect(getUrlsInTable()).toEqual(['/img2.jpg']);
|
|
434
|
+
filterCheckbox.click();
|
|
435
|
+
expect(getUrlsInTable()).toEqual(['/img1.jpg', '/img2.jpg', '/img3.jpg']);
|
|
436
|
+
const filter3pCount = dom.find('#modern-image-formats .lh-3p-filter-count', container);
|
|
437
|
+
expect(filter3pCount.textContent).toEqual('2');
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it('filters out sub-item rows of third party resources on click', () => {
|
|
441
|
+
dom.find('#unused-javascript', container);
|
|
442
|
+
const filterCheckbox = dom.find('#unused-javascript .lh-3p-filter-input', container);
|
|
443
|
+
|
|
444
|
+
function getRowIdentifiers() {
|
|
445
|
+
return dom
|
|
446
|
+
.findAll(
|
|
447
|
+
'#unused-javascript tbody tr:not(.lh-row--hidden)', container)
|
|
448
|
+
.map(el => el.textContent);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const initialExpected = [
|
|
452
|
+
'/script1.js(www.cdn.com)24.0 KiB8.8 KiB',
|
|
453
|
+
'10.0 KiB0.0 KiB',
|
|
454
|
+
'20.0 KiB0.0 KiB',
|
|
455
|
+
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
456
|
+
'30.0 KiB0.0 KiB',
|
|
457
|
+
'40.0 KiB0.0 KiB',
|
|
458
|
+
'/script3.js(www.notexample.com)24.0 KiB8.8 KiB',
|
|
459
|
+
'50.0 KiB0.0 KiB',
|
|
460
|
+
'60.0 KiB0.0 KiB',
|
|
461
|
+
];
|
|
462
|
+
|
|
463
|
+
expect(getRowIdentifiers()).toEqual(initialExpected);
|
|
464
|
+
filterCheckbox.click();
|
|
465
|
+
expect(getRowIdentifiers()).toEqual([
|
|
466
|
+
'/script2.js(www.example.com)24.0 KiB8.8 KiB',
|
|
467
|
+
'30.0 KiB0.0 KiB',
|
|
468
|
+
'40.0 KiB0.0 KiB',
|
|
469
|
+
]);
|
|
470
|
+
|
|
471
|
+
filterCheckbox.click();
|
|
472
|
+
expect(getRowIdentifiers()).toEqual(initialExpected);
|
|
473
|
+
const filter3pCount = dom.find('#unused-javascript .lh-3p-filter-count', container);
|
|
474
|
+
expect(filter3pCount.textContent).toEqual('2');
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('adds no filter for audits in thirdPartyFilterAuditExclusions', () => {
|
|
478
|
+
const checkboxClassName = 'lh-3p-filter-input';
|
|
479
|
+
|
|
480
|
+
const yesCheckbox = dom.find(`#modern-image-formats .${checkboxClassName}`, container);
|
|
481
|
+
expect(yesCheckbox).toBeTruthy();
|
|
482
|
+
|
|
483
|
+
expect(() => dom.find(`#uses-rel-preconnect .${checkboxClassName}`, container))
|
|
484
|
+
.toThrowError('query #uses-rel-preconnect .lh-3p-filter-input not found');
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it('filter is hidden when just third party resources', () => {
|
|
488
|
+
const filterControl =
|
|
489
|
+
dom.find('#render-blocking-resources .lh-3p-filter', container);
|
|
490
|
+
expect(filterControl.hidden).toEqual(true);
|
|
491
|
+
// Expect the hidden filter to still count third parties correctly.
|
|
492
|
+
const filter3pCount = dom.find('#render-blocking-resources .lh-3p-filter-count',
|
|
493
|
+
container);
|
|
494
|
+
expect(filter3pCount.textContent).toEqual('3');
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it('filter is hidden for just first party resources', () => {
|
|
498
|
+
const filterControl = dom.find('#uses-text-compression .lh-3p-filter', container);
|
|
499
|
+
expect(filterControl.hidden).toEqual(true);
|
|
500
|
+
// Expect the hidden filter to still count third parties correctly.
|
|
501
|
+
const filter3pCount = dom.find('#uses-text-compression .lh-3p-filter-count',
|
|
502
|
+
container);
|
|
503
|
+
expect(filter3pCount.textContent).toEqual('0');
|
|
504
|
+
});
|
|
278
505
|
});
|
|
279
506
|
});
|
|
280
507
|
|
|
@@ -98,6 +98,10 @@ describe('util helpers', () => {
|
|
|
98
98
|
it('corrects underscored `notApplicable` scoreDisplayMode', () => {
|
|
99
99
|
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
|
|
100
100
|
|
|
101
|
+
// Avoid injecting entity names into audits that would would
|
|
102
|
+
// make the diff at the end of this test difficult.
|
|
103
|
+
delete clonedSampleResult.entities;
|
|
104
|
+
|
|
101
105
|
let notApplicableCount = 0;
|
|
102
106
|
Object.values(clonedSampleResult.audits).forEach(audit => {
|
|
103
107
|
if (audit.scoreDisplayMode === 'notApplicable') {
|
|
@@ -117,6 +121,10 @@ describe('util helpers', () => {
|
|
|
117
121
|
it('corrects undefined auditDetails.type to `debugdata`', () => {
|
|
118
122
|
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
|
|
119
123
|
|
|
124
|
+
// Avoid injecting entity names into audits that would would
|
|
125
|
+
// make the diff at the end of this test difficult.
|
|
126
|
+
delete clonedSampleResult.entities;
|
|
127
|
+
|
|
120
128
|
// Delete debugdata details types.
|
|
121
129
|
let undefinedCount = 0;
|
|
122
130
|
for (const audit of Object.values(clonedSampleResult.audits)) {
|
|
@@ -136,6 +144,10 @@ describe('util helpers', () => {
|
|
|
136
144
|
it('corrects `diagnostic` auditDetails.type to `debugdata`', () => {
|
|
137
145
|
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
|
|
138
146
|
|
|
147
|
+
// Avoid injecting entity names into audits that would would
|
|
148
|
+
// make the diff at the end of this test difficult.
|
|
149
|
+
delete clonedSampleResult.entities;
|
|
150
|
+
|
|
139
151
|
// Change debugdata details types.
|
|
140
152
|
let diagnosticCount = 0;
|
|
141
153
|
for (const audit of Object.values(clonedSampleResult.audits)) {
|
|
@@ -155,6 +167,10 @@ describe('util helpers', () => {
|
|
|
155
167
|
it('corrects screenshots in the `filmstrip` auditDetails.type', () => {
|
|
156
168
|
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
|
|
157
169
|
|
|
170
|
+
// Avoid injecting entity names into audits that would would
|
|
171
|
+
// make the diff at the end of this test difficult.
|
|
172
|
+
delete clonedSampleResult.entities;
|
|
173
|
+
|
|
158
174
|
// Strip filmstrip screenshots of data URL prefix.
|
|
159
175
|
let filmstripCount = 0;
|
|
160
176
|
for (const audit of Object.values(clonedSampleResult.audits)) {
|
|
@@ -183,6 +199,9 @@ describe('util helpers', () => {
|
|
|
183
199
|
},
|
|
184
200
|
};
|
|
185
201
|
delete clonedSampleResult.fullPageScreenshot;
|
|
202
|
+
// Avoid injecting entity names into audits that would would
|
|
203
|
+
// make the diff at the end of this test difficult.
|
|
204
|
+
delete clonedSampleResult.entities;
|
|
186
205
|
|
|
187
206
|
assert.ok(clonedSampleResult.audits['full-page-screenshot'].details.nodes); // Make sure something's being tested.
|
|
188
207
|
assert.notDeepStrictEqual(clonedSampleResult.audits, sampleResult.audits);
|
|
@@ -218,6 +237,10 @@ describe('util helpers', () => {
|
|
|
218
237
|
it('converts old opportunity table column headings to consolidated table headings', () => {
|
|
219
238
|
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
|
|
220
239
|
|
|
240
|
+
// Avoid injecting entity names into audits that would would
|
|
241
|
+
// make the diff at the end of this test difficult.
|
|
242
|
+
delete clonedSampleResult.entities;
|
|
243
|
+
|
|
221
244
|
const auditsWithTableDetails = Object.values(clonedSampleResult.audits)
|
|
222
245
|
.filter(audit => audit.details?.type === 'table');
|
|
223
246
|
assert.notEqual(auditsWithTableDetails.length, 0);
|
|
@@ -266,6 +289,34 @@ describe('util helpers', () => {
|
|
|
266
289
|
const interactiveRef = perfAuditRefs.find(ref => ref.id === 'interactive');
|
|
267
290
|
assert.strictEqual(interactiveRef.stackPacks, undefined);
|
|
268
291
|
});
|
|
292
|
+
|
|
293
|
+
it('identifies entities on items of tables with urls', () => {
|
|
294
|
+
const clonedSampleResult = JSON.parse(JSON.stringify(sampleResult));
|
|
295
|
+
|
|
296
|
+
const auditsWithTableDetails = Object.values(clonedSampleResult.audits)
|
|
297
|
+
.filter(audit => audit.details?.type === 'table');
|
|
298
|
+
assert.notEqual(auditsWithTableDetails.length, 0);
|
|
299
|
+
|
|
300
|
+
// collect audit names that might have urls
|
|
301
|
+
const auditsThatDontHaveUrls = ['bf-cache', 'font-size']; // no urls in data-set
|
|
302
|
+
const auditsWithUrls = auditsWithTableDetails.filter(audit => {
|
|
303
|
+
if (auditsThatDontHaveUrls.includes(audit.id)) return false;
|
|
304
|
+
const urlFields = ['url', 'source-location'];
|
|
305
|
+
return audit.details.headings.some(heading =>
|
|
306
|
+
urlFields.includes(heading.valueType) ||
|
|
307
|
+
urlFields.includes(heading.subItemsHeading?.valueType)
|
|
308
|
+
);
|
|
309
|
+
}).map(audit => audit.id);
|
|
310
|
+
assert.notEqual(auditsWithUrls.length, 0);
|
|
311
|
+
|
|
312
|
+
const preparedResult = ReportUtils.prepareReportResult(clonedSampleResult);
|
|
313
|
+
|
|
314
|
+
// ensure each audit that had urls detected to have marked entities.
|
|
315
|
+
for (const id of auditsWithUrls) {
|
|
316
|
+
const foundEntities = preparedResult.audits[id].details.items.some(item => item.entity);
|
|
317
|
+
assert.equal(foundEntities, true);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
269
320
|
});
|
|
270
321
|
|
|
271
322
|
describe('#shouldDisplayAsFraction', () => {
|