Skip to content

Instantly share code, notes, and snippets.

@nucliweb
Created November 7, 2021 18:10
Show Gist options
  • Save nucliweb/23691ec2dde2c8f45c0a20df0830ae44 to your computer and use it in GitHub Desktop.
Save nucliweb/23691ec2dde2c8f45c0a20df0830ae44 to your computer and use it in GitHub Desktop.
Testing User Journey Web Performance with Vercel Store (Nov 7, 2021)
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
async function waitForSelectors(selectors, frame) {
for (const selector of selectors) {
try {
return await waitForSelector(selector, frame);
} catch (err) {
console.error(err);
}
}
throw new Error('Could not find element for selectors: ' + JSON.stringify(selectors));
}
async function waitForSelector(selector, frame) {
if (selector instanceof Array) {
let element = null;
for (const part of selector) {
if (!element) {
element = await frame.waitForSelector(part);
} else {
element = await element.$(part);
}
if (!element) {
throw new Error('Could not find element: ' + part);
}
element = (await element.evaluateHandle(el => el.shadowRoot ? el.shadowRoot : el)).asElement();
}
if (!element) {
throw new Error('Could not find element: ' + selector.join('|'));
}
return element;
}
const element = await frame.waitForSelector(selector);
if (!element) {
throw new Error('Could not find element: ' + selector);
}
return element;
}
async function waitForElement(step, frame) {
const count = step.count || 1;
const operator = step.operator || '>=';
const comp = {
'==': (a, b) => a === b,
'>=': (a, b) => a >= b,
'<=': (a, b) => a <= b,
};
const compFn = comp[operator];
await waitForFunction(async () => {
const elements = await querySelectorsAll(step.selectors, frame);
return compFn(elements.length, count);
});
}
async function querySelectorsAll(selectors, frame) {
for (const selector of selectors) {
const result = await querySelectorAll(selector, frame);
if (result.length) {
return result;
}
}
return [];
}
async function querySelectorAll(selector, frame) {
if (selector instanceof Array) {
let elements = [];
let i = 0;
for (const part of selector) {
if (i === 0) {
elements = await frame.$$(part);
} else {
const tmpElements = elements;
elements = [];
for (const el of tmpElements) {
elements.push(...(await el.$$(part)));
}
}
if (elements.length === 0) {
return [];
}
const tmpElements = [];
for (const el of elements) {
const newEl = (await el.evaluateHandle(el => el.shadowRoot ? el.shadowRoot : el)).asElement();
if (newEl) {
tmpElements.push(newEl);
}
}
elements = tmpElements;
i++;
}
return elements;
}
const element = await frame.$$(selector);
if (!element) {
throw new Error('Could not find element: ' + selector);
}
return element;
}
async function waitForFunction(fn) {
let isActive = true;
setTimeout(() => {
isActive = false;
}, 5000);
while (isActive) {
const result = await fn();
if (result) {
return;
}
await new Promise(resolve => setTimeout(resolve, 100));
}
throw new Error('Timed out');
}
{
const targetPage = page;
await targetPage.setViewport({"width":1285,"height":925})
}
{
const targetPage = page;
const promises = [];
promises.push(targetPage.waitForNavigation());
await targetPage.goto('https://demo.vercel.store/');
await Promise.all(promises);
}
{
const targetPage = page;
await targetPage.evaluate((x, y) => { window.scroll(x, y); }, 0, 2)
}
{
const targetPage = page;
const element = await waitForSelectors([["#__next > div > main > div.Grid_root__2GDws.Grid_layoutA__2eEzQ.Grid_filled__2x5Xm > a:nth-child(3) > div.ProductCard_imageContainer__bPqUi > div > img"]], targetPage);
await element.click({ offset: { x: 309.5638427734375, y: 233.87637329101562} });
}
{
const targetPage = page;
await targetPage.evaluate((x, y) => { window.scroll(x, y); }, 0, 0)
}
{
const targetPage = page;
const element = await waitForSelectors([["aria/Add to Cart"],["#__next > div > main > div > div > div.ProductView_sidebar__17Whl > div:nth-child(4) > button"]], targetPage);
await element.click({ offset: { x: 194.671875, y: 34} });
}
{
const targetPage = page;
const promises = [];
promises.push(targetPage.waitForNavigation());
const element = await waitForSelectors([["aria/PROCEED TO CHECKOUT"],["#__next > div > div.Sidebar_root__gdPr3 > div > section > div > div > div > div > div.flex-shrink-0.px-6.py-6.sm\\:px-6.sticky.z-20.bottom-0.w-full.right-0.left-0.bg-accent-0.border-t.text-sm > div:nth-child(3) > a"]], targetPage);
await element.click({ offset: { x: 233, y: 21} });
await Promise.all(promises);
}
await browser.close();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment