Skip to content

Commit

Permalink
Add user-interaction script
Browse files Browse the repository at this point in the history
  • Loading branch information
pedddro committed Feb 20, 2024
1 parent 3dc5226 commit a0d2e91
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["javascript"]
}
6 changes: 4 additions & 2 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Utilizes the source code available the [Web Vitals](https://github.com/GoogleChr

## Configure

Tweak the following lines in `index.js`:
Tweak the following lines in `index.js` or `index_int.js`(if you wan to simulate user-interaction):

```
// TODO, Change here to the element you would like Puppeteer to interact with.
Expand All @@ -19,7 +19,7 @@ const navigateTo = "https://www.example.com/";
## How to run?

1. From the root folder of the project run `npm init`
2. Run `node index.js`
2. Run `node index.js` or `node index_int.js`

When we run the project a browser will open and we will observe a simulation of user journey.

Expand All @@ -36,6 +36,8 @@ inp: 264

We have a shell script that can run a simulation multiple times. At the moment we run a simulation 10 times.

Change `index.js` for `index_int.js` if you want to run many user-interaction simulations.

Try:

```
Expand Down
9 changes: 5 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const fs = require("fs");
const path = require("path");

const puppeteer = require("puppeteer");
const { PuppeteerScreenRecorder } = require("puppeteer-screen-recorder");
// const { PuppeteerScreenRecorder } = require("puppeteer-screen-recorder");

const recording = false;

Expand All @@ -11,10 +11,11 @@ const CWV = require("./src/CWV");
const DeviceEmulation = require("./src/DeviceEmulation");

// TODO, Change here to the element you would like Puppeteer to interact with.
const elementToInteractWith = "### ADD THE CSS SELECTOR HERE ###";
const elementToInteractWith = "A.wp-block-button__link";

// TODO, Change here to the url you would like to load in Puppeteer.
const navigateTo = "https://www.example.com/";
//add ?nowprocket=1 to override wp rocket
const navigateTo = "https://www.spendwithpennies.com/";

var args = process.argv.slice(2);

Expand Down Expand Up @@ -75,7 +76,7 @@ else {
const overrideContent = fs.readFileSync(path.join(__dirname, "overrides", "example-js-of-interest.js"), "utf8");
interceptedRequest.respond({
status: 200,
contentType: "application/javascript; charset=utf-8",
contentType: "text/javascript; charset=utf-8",
body: overrideContent
});
return;
Expand Down
158 changes: 158 additions & 0 deletions index_int.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
const fs = require("fs");
const path = require("path");

const puppeteer = require("puppeteer");
// const { PuppeteerScreenRecorder } = require("puppeteer-screen-recorder");

const recording = false;

const Cookies = require("./src/Cookies");
const CWV = require("./src/CWV");
const DeviceEmulation = require("./src/DeviceEmulation");

// TODO, Change here to the element you would like Puppeteer to interact with.
const elementToInteractWith = "### ADD THE CSS SELECTOR HERE ###";

// TODO, Change here to the url you would like to load in Puppeteer.
const navigateTo = "https://www.example.com/";

var args = process.argv.slice(2);

let experiment = 0;

if (args[0]) {
const paramParts = args[0].split("=");

if (paramParts[0] === "experiment") {
experiment = parseInt(paramParts[1]);
}
}

if (experiment === 0) {
console.log("Running on the original page.");
}
else {
console.log("Running experiment {" + experiment + "} on a modified page.");
}

(async() => {
const browser = await puppeteer.launch({ headless: false });

const page = await browser.newPage();

if (recording) {
// Configure the screen recorder
const recorder = new PuppeteerScreenRecorder(page, {
followNewTab: true,
fps: 30,
videoFrame: {
width: 1080,
height: 2400
}
// Other configurations
});

await recorder.start("output.mp4");
}

await DeviceEmulation.emulate(page);

// Listen for console events within the page and log them in Node.js context
page.on("console", (msg) => {
console.log(msg.text());
});

// Enable request interception
await page.setRequestInterception(true);

// Add event listener to intercept requests
page.on("request", (interceptedRequest) => {
// Check if the request is for the resource you want to override
if (interceptedRequest.url().endsWith("example-js-of-interest.js")) {
console.log("Intercepted and overriding: " + interceptedRequest.url());

// Create a response from a local file
const overrideContent = fs.readFileSync(path.join(__dirname, "overrides", "example-js-of-interest.js"), "utf8");
interceptedRequest.respond({
status: 200,
contentType: "text/javascript; charset=utf-8",
body: overrideContent
});
return;
}

// Allow all other requests to continue normally
interceptedRequest.continue();
});

// Navigate to the page
await page.goto(navigateTo);

await CWV.attachCWV_Lib(page);

await Cookies.setOptanonConsent(page);

// Wait for a specified timeout in milliseconds
await page.waitForTimeout(2500); // waits for 2.5 seconds

// Simulate user-interaction
await autoScroll(page);

// Wait for the element to be present in the DOM
await page.waitForSelector(elementToInteractWith);

// Click the input input
await page.click(elementToInteractWith);
await page.focus(elementToInteractWith);

await page.waitForTimeout(2500); // waits for 2.5 seconds

// Execute JS code after the timeout
await page.evaluateHandle(() => {
window.webVitals.getINP(function(info) {
if (info.value) {
console.log("inp: " + info.value);
}
else {
console.log("inp: not measured");
}
},
{
reportAllChanges: true
}
);
});

await page.waitForTimeout(5000); // waits for 5 seconds

if (recording) {
// Stop recording
await recorder.stop();
}

// You can close the browser after a timeout, or after some specific action
// that would ensure all metrics have been captured.
await browser.close();
})();

// scroll to simulate interaction
async function autoScroll(page){
await page.evaluate(async () => {
await new Promise((resolve) => {
// page height
var totalHeight = 0;
//scroll distance
var distance = 55;
var timer = setInterval(() => {
var scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;

if(totalHeight >= scrollHeight - window.innerHeight){
clearInterval(timer);
resolve();
}
}, 100);
});
});
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "inp-measure-puppeteer",
"version": "1.0.0",
"description": "",
"description": "Very experimental and still in a proof of concept stage but it does the trick.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
Expand Down
4 changes: 3 additions & 1 deletion run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ for i in {1..10}; do
node "$PUPPETEER_SCRIPT" $1
done

echo "Script completed."
echo "Script completed."

$SHELL

0 comments on commit a0d2e91

Please sign in to comment.