-
-
Save nucliweb/23691ec2dde2c8f45c0a20df0830ae44 to your computer and use it in GitHub Desktop.
Testing User Journey Web Performance with Vercel Store (Nov 7, 2021)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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