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

report(flow): full page screenshot renderer #13276

Merged
merged 2 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 8 additions & 8 deletions flow-report/src/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {FunctionComponent} from 'preact';
import {useEffect, useState} from 'preact/hooks';

import {NavigationIcon, SnapshotIcon, TimespanIcon} from './icons';
import {getFilmstripFrames, getScreenDimensions, getScreenshot} from './util';
import {getFilmstripFrames, getScreenDimensions, getFullPageScreenshot} from './util';

const ANIMATION_FRAME_DURATION_MS = 500;

Expand Down Expand Up @@ -72,15 +72,15 @@ const FlowStepAnimatedThumbnail: FunctionComponent<{
};

export const FlowStepThumbnail: FunctionComponent<{
reportResult: LH.ReportResult,
lhr: LH.Result,
width?: number,
height?: number,
}> = ({reportResult, width, height}) => {
const screenshot = getScreenshot(reportResult);
const frames = getFilmstripFrames(reportResult);
}> = ({lhr, width, height}) => {
const screenshot = getFullPageScreenshot(lhr);
const frames = getFilmstripFrames(lhr);

// Resize the image to fit the viewport aspect ratio.
const dimensions = getScreenDimensions(reportResult);
const dimensions = getScreenDimensions(lhr);
if (width && height === undefined) {
height = dimensions.height * width / dimensions.width;
} else if (height && width === undefined) {
Expand All @@ -92,7 +92,7 @@ export const FlowStepThumbnail: FunctionComponent<{
return <></>;
}

if (reportResult.gatherMode === 'timespan' && frames && frames.length) {
if (lhr.gatherMode === 'timespan' && frames && frames.length) {
return <FlowStepAnimatedThumbnail frames={frames} width={width} height={height} />;
}

Expand All @@ -101,7 +101,7 @@ export const FlowStepThumbnail: FunctionComponent<{
screenshot &&
<img
className="FlowStepThumbnail"
src={screenshot}
src={screenshot.screenshot.data}
style={{width, height}}
alt="Screenshot of a page tested by Lighthouse"
/>
Expand Down
15 changes: 7 additions & 8 deletions flow-report/src/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import {FunctionComponent} from 'preact';

import {Util} from '../../report/renderer/util';
import {FlowStepIcon, FlowStepThumbnail} from './common';
import {useLocalizedStrings} from './i18n/i18n';
import {getModeDescription, useFlowResult} from './util';
Expand All @@ -15,16 +14,16 @@ const SIDE_THUMBNAIL_HEIGHT = 80;
const MAIN_THUMBNAIL_HEIGHT = 120;

const HeaderThumbnail: FunctionComponent<{
reportResult: LH.ReportResult,
lhr: LH.Result,
position: 'prev'|'next'|'main'
}> =
({reportResult, position}) => {
({lhr, position}) => {
const height = position === 'main' ? MAIN_THUMBNAIL_HEIGHT : SIDE_THUMBNAIL_HEIGHT;
return (
<div className={`HeaderThumbnail HeaderThumbnail--${position}`}>
<FlowStepThumbnail reportResult={reportResult} height={height}/>
<FlowStepThumbnail lhr={lhr} height={height}/>
<div className="HeaderThumbnail__icon">
<FlowStepIcon mode={reportResult.gatherMode}/>
<FlowStepIcon mode={lhr.gatherMode}/>
</div>
</div>
);
Expand All @@ -50,7 +49,7 @@ export const Header: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
flowResult.steps[index - 2] && <div className="Header__segment"/>
}
<div className="Header__prev-thumbnail">
<HeaderThumbnail reportResult={Util.prepareReportResult(prevStep.lhr)} position="prev"/>
<HeaderThumbnail lhr={prevStep.lhr} position="prev"/>
<div className="Header__segment"/>
</div>
<a
Expand All @@ -60,7 +59,7 @@ export const Header: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
</>
}
<div className="Header__current-thumbnail">
<HeaderThumbnail reportResult={Util.prepareReportResult(step.lhr)} position="main"/>
<HeaderThumbnail lhr={step.lhr} position="main"/>
</div>
<div className="Header__current-title">
{step.name}
Expand All @@ -72,7 +71,7 @@ export const Header: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
nextStep && <>
<div className="Header__next-thumbnail">
<div className="Header__segment"/>
<HeaderThumbnail reportResult={Util.prepareReportResult(nextStep.lhr)} position="next"/>
<HeaderThumbnail lhr={nextStep.lhr} position="next"/>
</div>
<a
className="Header__next-title"
Expand Down
2 changes: 1 addition & 1 deletion flow-report/src/summary/summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const SummaryFlowStep: FunctionComponent<{
<Separator/>
</div>
}
<FlowStepThumbnail reportResult={reportResult} width={THUMBNAIL_WIDTH}/>
<FlowStepThumbnail lhr={lhr} width={THUMBNAIL_WIDTH}/>
<FlowSegment mode={lhr.gatherMode}/>
<div className="SummaryFlowStep__label">
<div className="SummaryFlowStep__mode">{modeDescription}</div>
Expand Down
8 changes: 4 additions & 4 deletions flow-report/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,24 @@ export function classNames(...args: Array<string|undefined|Record<string, boolea
return classes.join(' ');
}

export function getScreenDimensions(reportResult: LH.ReportResult) {
export function getScreenDimensions(reportResult: LH.Result) {
const {width, height} = reportResult.configSettings.screenEmulation;
return {width, height};
}

export function getScreenshot(reportResult: LH.ReportResult) {
export function getFullPageScreenshot(reportResult: LH.Result) {
const fullPageScreenshotAudit = reportResult.audits['full-page-screenshot'];
const fullPageScreenshot =
fullPageScreenshotAudit &&
fullPageScreenshotAudit.details &&
fullPageScreenshotAudit.details.type === 'full-page-screenshot' &&
fullPageScreenshotAudit.details.screenshot.data;
fullPageScreenshotAudit.details;

return fullPageScreenshot || null;
}

export function getFilmstripFrames(
reportResult: LH.ReportResult
reportResult: LH.Result
): Array<{data: string}> | undefined {
const filmstripAudit = reportResult.audits['screenshot-thumbnails'];
if (!filmstripAudit) return undefined;
Expand Down
12 changes: 12 additions & 0 deletions flow-report/src/wrappers/report.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import {FunctionComponent} from 'preact';
import {useLayoutEffect, useRef} from 'preact/hooks';

import {ElementScreenshotRenderer} from '../../../report/renderer/element-screenshot-renderer';
import {getFullPageScreenshot} from '../util';
import {useReportRenderer} from './report-renderer';

/**
Expand Down Expand Up @@ -41,6 +43,16 @@ export const Report: FunctionComponent<{currentLhr: LH.FlowResult.LhrRef}> =
dom.clearComponentCache();
reportRenderer.renderReport(currentLhr.value, ref.current);
convertChildAnchors(ref.current, currentLhr.index);
const fullPageScreenshot = getFullPageScreenshot(currentLhr.value);
if (fullPageScreenshot) {
const container = dom.find('.lh-container', ref.current);
ElementScreenshotRenderer.installOverlayFeature({
dom,
reportEl: container,
overlayContainerEl: container,
fullPageScreenshot,
});
}
const topbar = ref.current.querySelector('.lh-topbar');
if (topbar) topbar.remove();
}
Expand Down
12 changes: 6 additions & 6 deletions flow-report/test/common-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {act, render} from '@testing-library/preact';

import {FlowStepThumbnail} from '../src/common';

let lhr: LH.ReportResult;
let lhr: LH.Result;

jest.useFakeTimers();

Expand All @@ -33,30 +33,30 @@ describe('FlowStepThumbnail', () => {
});

it('renders a thumbnail', () => {
const root = render(<FlowStepThumbnail reportResult={lhr} width={200} height={200} />);
const root = render(<FlowStepThumbnail lhr={lhr} width={200} height={200} />);

const thumbnail = root.getByAltText(/Screenshot/);
expect(thumbnail.style.width).toEqual('200px');
expect(thumbnail.style.height).toEqual('200px');
});

it('renders nothing without dimensions', () => {
const root = render(<FlowStepThumbnail reportResult={lhr} />);
const root = render(<FlowStepThumbnail lhr={lhr} />);

expect(() => root.getByAltText(/Screenshot/)).toThrow();
expect(global.console.warn).toHaveBeenCalled();
});

it('interpolates height', () => {
const root = render(<FlowStepThumbnail reportResult={lhr} width={200} />);
const root = render(<FlowStepThumbnail lhr={lhr} width={200} />);

const thumbnail = root.getByAltText(/Screenshot/);
expect(thumbnail.style.width).toEqual('200px');
expect(thumbnail.style.height).toEqual('300px');
});

it('interpolates width', () => {
const root = render(<FlowStepThumbnail reportResult={lhr} height={150} />);
const root = render(<FlowStepThumbnail lhr={lhr} height={150} />);

const thumbnail = root.getByAltText(/Screenshot/);
expect(thumbnail.style.width).toEqual('100px');
Expand All @@ -74,7 +74,7 @@ describe('FlowStepThumbnail', () => {
],
},
} as any;
const root = render(<FlowStepThumbnail reportResult={lhr} height={150} />);
const root = render(<FlowStepThumbnail lhr={lhr} height={150} />);

const thumbnail = root.getByAltText(/Animated/) as HTMLImageElement;
expect(thumbnail.style.width).toEqual('100px');
Expand Down