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

core(replay): @puppeteer/replay stringify extension #14146

Merged
merged 29 commits into from
Aug 16, 2022
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
1 change: 1 addition & 0 deletions .github/workflows/unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:

- run: yarn install --frozen-lockfile --network-timeout 1000000
- run: yarn build-report
- run: yarn reset-link
Copy link
Member

Choose a reason for hiding this comment

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

is this required to run unit tests after this change?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes


# Run pptr tests using ToT Chrome instead of stable default.
- name: Define ToT chrome path
Expand Down
22 changes: 22 additions & 0 deletions cli/test/fixtures/flow/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!--
* Copyright 2022 The Lighthouse Authors. 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.
-->
<html>
<body>
<div id="list"></div>
<h1>Landing page for our user flows!</h1>
<button id="add-item">Add item</button>
<a id="link" href="/flow/next.html">Link to new page!</a>
</body>
<script>
const button = document.getElementById('add-item');
button.onclick = async () => {
const list = document.getElementById('list');
const item = document.createElement('h3');
item.textContent = 'New item!';
list.append(item);
}
</script>
</html>
15 changes: 15 additions & 0 deletions cli/test/fixtures/flow/next.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!--
* Copyright 2022 The Lighthouse Authors. 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.
-->
<html>
<body>
<h1>New page after clicking the link!</h1>
<details id="content">
<summary>Hidden content here:</summary>
Hello there!
</details>
</body>
</html>

107 changes: 107 additions & 0 deletions core/fraggle-rock/replay/stringify-extension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* @license Copyright 2022 The Lighthouse Authors. 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';

import * as PuppeteerReplay from '@puppeteer/replay';

/**
* @param {PuppeteerReplay.Schema.Step} step
* @return {boolean}
*/
function isNavigationStep(step) {
return Boolean(
step.type === 'navigate' ||
step.assertedEvents?.some(event => event.type === 'navigation')
);
}

class LighthouseStringifyExtension extends PuppeteerReplay.PuppeteerStringifyExtension {
#isProcessingTimespan = false;

/**
* @override
* @param {PuppeteerReplay.LineWriter} out
* @param {PuppeteerReplay.Schema.UserFlow} flow
*/
async beforeAllSteps(out, flow) {
out.appendLine(`const fs = require('fs');`);

let isMobile = true;
for (const step of flow.steps) {
if (step.type !== 'setViewport') continue;
isMobile = step.isMobile;
}

await super.beforeAllSteps(out, flow);

const configContext = {
settingsOverrides: {
screenEmulation: {
disabled: true,
},
},
};
out.appendLine(`const configContext = ${JSON.stringify(configContext)}`);
if (isMobile) {
out.appendLine(`const config = undefined;`);
} else {
// eslint-disable-next-line max-len
out.appendLine(`const config = (await import('lighthouse/core/config/desktop-config.js')).default;`);
}

out.appendLine(`const lhApi = await import('lighthouse/core/fraggle-rock/api.js');`);
// eslint-disable-next-line max-len
out.appendLine(`const lhFlow = await lhApi.startFlow(page, {name: ${JSON.stringify(flow.title)}, config, configContext});`);
}

/**
* @override
* @param {PuppeteerReplay.LineWriter} out
* @param {PuppeteerReplay.Schema.Step} step
* @param {PuppeteerReplay.Schema.UserFlow} flow
*/
async stringifyStep(out, step, flow) {
if (step.type === 'setViewport') {
await super.stringifyStep(out, step, flow);
return;
}

const isNavigation = isNavigationStep(step);

if (isNavigation) {
if (this.#isProcessingTimespan) {
out.appendLine(`await lhFlow.endTimespan();`);
this.#isProcessingTimespan = false;
}
out.appendLine(`await lhFlow.startNavigation();`);
} else if (!this.#isProcessingTimespan) {
out.appendLine(`await lhFlow.startTimespan();`);
this.#isProcessingTimespan = true;
}

await super.stringifyStep(out, step, flow);

if (isNavigation) {
out.appendLine(`await lhFlow.endNavigation();`);
}
}

/**
* @override
* @param {PuppeteerReplay.LineWriter} out
* @param {PuppeteerReplay.Schema.UserFlow} flow
*/
async afterAllSteps(out, flow) {
if (this.#isProcessingTimespan) {
out.appendLine(`await lhFlow.endTimespan();`);
}
out.appendLine(`const lhFlowReport = await lhFlow.generateReport();`);
out.appendLine(`fs.writeFileSync(__dirname + '/flow.report.html', lhFlowReport)`);
await super.afterAllSteps(out, flow);
}
}

export default LighthouseStringifyExtension;
102 changes: 102 additions & 0 deletions core/test/fixtures/fraggle-rock/replay/desktop-test-flow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"title": "Test Flow on Desktop",
"steps": [
{
"type": "setViewport",
"width": 757,
"height": 988,
"deviceScaleFactor": 1,
"isMobile": false,
"hasTouch": false,
"isLandscape": false
},
{
"type": "navigate",
"url": "http://localhost:10200/flow/index.html",
"assertedEvents": [
{
"type": "navigation",
"url": "http://localhost:10200/flow/index.html",
"title": ""
}
]
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Add item"
],
[
"#add-item"
]
],
"offsetY": 13.5625,
"offsetX": 61
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Add item"
],
[
"#add-item"
]
],
"offsetY": 4.125,
"offsetX": 42
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Add item"
],
[
"#add-item"
]
],
"offsetY": 8.40625,
"offsetX": 50
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Link to new page!"
],
[
"#link"
]
],
"offsetY": 3.6875,
"offsetX": 53.390625,
"assertedEvents": [
{
"type": "navigation",
"url": "http://localhost:10200/flow/next.html",
"title": ""
}
]
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Hidden content here:"
],
[
"#content > summary"
]
],
"offsetY": 10.5625,
"offsetX": 6
}
]
}
102 changes: 102 additions & 0 deletions core/test/fixtures/fraggle-rock/replay/mobile-test-flow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"title": "Test Flow on Mobile",
"steps": [
{
"type": "setViewport",
"width": 300,
"height": 600,
"deviceScaleFactor": 3,
"isMobile": true,
"hasTouch": true,
"isLandscape": false
},
{
"type": "navigate",
"url": "http://localhost:10200/flow/index.html",
"assertedEvents": [
{
"type": "navigation",
"url": "http://localhost:10200/flow/index.html",
"title": ""
}
]
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Add item"
],
[
"#add-item"
]
],
"offsetY": 13.5625,
"offsetX": 61
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Add item"
],
[
"#add-item"
]
],
"offsetY": 4.125,
"offsetX": 42
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Add item"
],
[
"#add-item"
]
],
"offsetY": 8.40625,
"offsetX": 50
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Link to new page!"
],
[
"#link"
]
],
"offsetY": 3.6875,
"offsetX": 53.390625,
"assertedEvents": [
{
"type": "navigation",
"url": "http://localhost:10200/flow/next.html",
"title": ""
}
]
},
{
"type": "click",
"target": "main",
"selectors": [
[
"aria/Hidden content here:"
],
[
"#content > summary"
]
],
"offsetY": 10.5625,
"offsetX": 6
}
]
}
Loading