Skip to content

core(full-page-screenshot): add full page screenshot to artifacts#9064

Closed
mattzeunert wants to merge 6 commits into
masterfrom
full-page-screenshot
Closed

core(full-page-screenshot): add full page screenshot to artifacts#9064
mattzeunert wants to merge 6 commits into
masterfrom
full-page-screenshot

Conversation

@mattzeunert

@mattzeunert mattzeunert commented May 26, 2019

Copy link
Copy Markdown
Contributor

Capture a screenshot of the entire page, rather than just the above the fold content.

Splitting this off from this PR which actually uses the artifact.

What's the best way to test this? Add a new smoke test and unit test the gatherer with a mocked driver?

Related Issues/PRs

Part of #7327

await emulation.enableNexus5X(this, deviceMetricOverrides);
} else if (settings.emulatedFormFactor === 'desktop') {
await emulation.enableDesktop(this);
await emulation.enableDesktop(this, deviceMetricOverrides);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be appropriate to hook the options on the driver itself?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by that?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the extra param could be removed in favor for having it as a prop on this

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we want to clutter driver with additional properties just for the method here. It's a pretty busy class already 😆

@patrickhulce patrickhulce left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good! I might argue that if we're commenting out the audit we should probably not land the gatherer config change either, but most of this depends on how quickly we'll follow this up with user-facing changes to leverage this.

data,
width,
height,
// todo: do we need these? should we create a new type? should we make them optional on the existing type? should we try to provide accurate values?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we should just nix these from the type

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. It makes sense to have the timings for the filmstrip, but Filmstrip is a separate type from Screenshot.

async _takeScreenshot(passContext, maxScreenshotHeight) {
const driver = passContext.driver;
const metrics = await driver.sendCommand('Page.getLayoutMetrics');
const width = await driver.evaluateAsync(`window.innerWidth`) * 2;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why * 2?

I thought we might want innerWidth * devicePixelRatio but then we force the deviceScaleFactor to 1 below so I'm not sure anymore

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, that slipped in when testing large screenshots.


const Gatherer = require('./gatherer.js');

// JPEG quality setting

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we link to that awesome exploration doc you made for how we landed on 30?

* @return {Promise<void>}
*/
async beginEmulation(settings) {
async beginEmulation(settings, deviceMetricOverrides) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my initial thought looking at this was that I was worried about emulatedFormFactor conflicting with deviceMetricOverrides, maybe add a brief comment explaining the use case for deviceMetricOverrides?

creating a nexus 5x with arbitrary screen height seems counter-intuitive at first :)

const height = Math.min(metrics.contentSize.height, maxScreenshotHeight);

await driver.beginEmulation(passContext.settings, {
height,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly talking to the air here did we ever figure out what screenHeight does separately from height? desktop doesn't set screenHeight at the moment at all just wonder if that'll impact anything

it sets the screen rect but not sure what impact that has...
https://cs.chromium.org/chromium/src/content/renderer/render_widget_screen_metrics_emulator.cc?type=cs&sq=package:chromium&g=0&l=78-83

seems like it notifies some observers and kicks off orientation changes, but doesn't actually affect viewport size?
https://cs.chromium.org/chromium/src/content/renderer/render_widget.cc?type=cs&sq=package:chromium&g=0&l=2183

🤷‍♂

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@connorjclark connorjclark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: command for viewing fullscreen image (after you run LH with -G)

(echo -e '<img src=' && (jq .FullPageScreenshot.data latest-run/artifacts.json | tr -d '\n') && echo -e '>') | cat > /tmp/lhfull.html && google-chrome /tmp/lhfull.html

const height = Math.min(metrics.contentSize.height, maxScreenshotHeight);

await driver.beginEmulation(passContext.settings, {
height,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* @return {Promise<LH.Artifacts.FullPageScreenshot>}
*/
async afterPass(passContext) {
let screenshot = await this._takeScreenshot(passContext, MAX_SCREENSHOT_HEIGHT);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we scroll to the top of the page first? I think devtools does that.

{deviceMetrics, setTouchEmulationEnabled, userAgent, deviceMetricOverrides}
) {
if (deviceMetricOverrides) {
deviceMetrics = Object.assign({}, deviceMetrics, deviceMetricOverrides);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
deviceMetrics = Object.assign({}, deviceMetrics, deviceMetricOverrides);
deviceMetrics = {...deviceMetrics, ...deviceMetricOverrides};

driver.sendCommand('Network.enable'),
driver.sendCommand('Network.setUserAgentOverride', {userAgent: NEXUS5X_USERAGENT}),
driver.sendCommand('Emulation.setTouchEmulationEnabled', {enabled: true}),
driver.sendCommand('Network.setUserAgentOverride', {userAgent}),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we be balancing domain enable / disable?


/**
* @param {LH.Config.Settings} settings
* @param {{height?: number, screenHeight: number?, deviceScaleFactor?: number}} [deviceMetricOverrides]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {{height?: number, screenHeight: number?, deviceScaleFactor?: number}} [deviceMetricOverrides]
* @param {{height?: number, screenHeight?: number, deviceScaleFactor?: number}} [deviceMetricOverrides]

height: 5000,
screenHeight: 5000,
},
]);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make expectations on the artifact too?

@connorjclark

connorjclark commented Sep 2, 2020

Copy link
Copy Markdown
Collaborator

we did this in #10716

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants