Skip to content

Commit

Permalink
feature(webpage-impact): add support for custom user interactions
Browse files Browse the repository at this point in the history
Signed-off-by: alexzurbonsen <[email protected]>
  • Loading branch information
alexzurbonsen committed Oct 27, 2024
1 parent 89b300d commit a550a86
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
3 changes: 2 additions & 1 deletion example-manifests/measure-webpage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ initialize:
path: '@tngtech/if-webpage-plugins'
config:
scrollToBottom: true
url: https://www.tngtech.com
url: https://www.sueddeutsche.de
customUserInteraction: '/absolute/path/to/your/script.js'
'co2js':
method: Co2js
path: '@tngtech/if-webpage-plugins'
Expand Down
27 changes: 27 additions & 0 deletions src/lib/webpage-impact/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ The follwing config parameters are optional:
- `accept`: string https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept
- `accept-encoding`: array of allowed encodings (a single encoding can also be passed as a string) https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding

Experimental:

- `customUserInteraction`: absolute path to a Javascript Common JS module, that exports a function with the signature `userInteraction: (page: Page) => Promise<void>`. For an example see below. Setting `customUserInteraction` cannot be set together with `scrollToBottom`.

### Returns

- `network/data/bytes`: page weight in bytes
Expand Down Expand Up @@ -80,3 +84,26 @@ tree:
- webpage-impact
inputs:
```
## Experimental: Custom user interactions
Example script:
```js
const userInteraction = async page => {
// on tngtech.com click on the "Leistungen" link
await page.locator('#menu > ul > li:nth-child(1) > a').click();
await page.waitForNavigation();

// for debugging purposes
await page.screenshot({
path: '/absolute/path/image.png',
});
};

exports.userInteraction = userInteraction;
```

Puppeteer docs on page interactions: https://pptr.dev/guides/page-interactions

TODO: How to deal with the reload option?
43 changes: 39 additions & 4 deletions src/lib/webpage-impact/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type WebpageImpactOptions = {
reload: boolean;
cacheEnabled: boolean;
scrollToBottom?: boolean;
customUserInteraction?: string;
};

type ResourceBase = {
Expand All @@ -36,6 +37,10 @@ type Resource = ResourceBase & {transferSize: number};

type Device = keyof typeof KnownDevices;

interface CustomUserInteraction {
userInteraction: (page: Page) => Promise<void>;
}

const LOGGER_PREFIX = 'WebpageImpact';

const ALLOWED_ENCODINGS = [
Expand Down Expand Up @@ -180,6 +185,7 @@ const WebpageImpactUtils = () => {
reload: false,
cacheEnabled: false,
scrollToBottom: config?.scrollToBottom,
customUserInteraction: config?.customUserInteraction,
});

let reloadedResources: Resource[] | undefined;
Expand Down Expand Up @@ -207,7 +213,12 @@ const WebpageImpactUtils = () => {
const loadPageResources = async (
page: Page,
url: string,
{reload, cacheEnabled, scrollToBottom}: WebpageImpactOptions
{
reload,
cacheEnabled,
scrollToBottom,
customUserInteraction,
}: WebpageImpactOptions
): Promise<Resource[]> => {
try {
await page.setCacheEnabled(cacheEnabled);
Expand Down Expand Up @@ -258,14 +269,19 @@ const WebpageImpactUtils = () => {

if (!reload) {
await page.goto(url, {waitUntil: 'networkidle0'});
if (customUserInteraction) {
const module = await import(customUserInteraction);
if (iscustomUserInteraction(module)) {
await module.userInteraction(page);
}
}
} else {
console.log('before reload');
await page.reload({waitUntil: 'networkidle0'});
}

if (scrollToBottom) {
// await page.screenshot({path: './TOP.png'});
if (!customUserInteraction && scrollToBottom) {
await page.evaluate(scrollToBottomOfPage);
// await page.screenshot({path: './BOTTOM.png'});
}

await cdpSession.detach();
Expand All @@ -278,6 +294,15 @@ const WebpageImpactUtils = () => {
}
};

const iscustomUserInteraction = (
customUserInteraction: any
): customUserInteraction is CustomUserInteraction => {
return (
'userInteraction' in customUserInteraction &&
typeof customUserInteraction['userInteraction'] === 'function'
);
};

const mergeCdpData = (
cdpResponses: Record<string, ResourceBase>,
cdpTransferSizes: Record<string, {transferSize: number}>
Expand Down Expand Up @@ -378,6 +403,7 @@ const WebpageImpactUtils = () => {
mobileDevice: z.string().optional(),
emulateNetworkConditions: z.string().optional(),
scrollToBottom: z.boolean().optional(),
customUserInteraction: z.string().optional(),
headers: z
.object({
accept: z.string().optional(),
Expand Down Expand Up @@ -425,6 +451,15 @@ const WebpageImpactUtils = () => {
PredefinedNetworkConditions
).join(', ')}.`,
}
)
.refine(
data => {
return !(data?.scrollToBottom && data?.customUserInteraction);
},
{
message:
'`scrollToBottom: true` and `customUserInteraction` cannot be provided together.',
}
);

return validate<z.infer<typeof configSchema>>(configSchema, config);
Expand Down

0 comments on commit a550a86

Please sign in to comment.