Created
October 26, 2022 10:17
-
-
Save arieffikhrie/a48fd63fc893b93de9ba538a318925a8 to your computer and use it in GitHub Desktop.
Test puppeteer on google.com
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-core"); // v13.0.0 or later | |
const path = require("path"); | |
(async () => { | |
const browser = await puppeteer.launch({ | |
executablePath: | |
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe", | |
}); | |
const page = await browser.newPage(); | |
const timeout = 5000; | |
page.setDefaultTimeout(timeout); | |
{ | |
const targetPage = page; | |
await targetPage.setViewport({ width: 1861, height: 472 }); | |
} | |
{ | |
const targetPage = page; | |
const promises = []; | |
promises.push(targetPage.waitForNavigation()); | |
await targetPage.goto("https://www.google.com/"); | |
await Promise.all(promises); | |
} | |
{ | |
const targetPage = page; | |
const element = await waitForSelectors( | |
[ | |
["aria/Search"], | |
[ | |
"body > div.L3eUgb > div.o3j99.ikrT4e.om7nvf > form > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input", | |
], | |
], | |
targetPage, | |
{ timeout, visible: true } | |
); | |
await scrollIntoViewIfNeeded(element, timeout); | |
await element.click({ | |
offset: { | |
x: 150.09088134765625, | |
y: 20.5, | |
}, | |
}); | |
} | |
{ | |
const targetPage = page; | |
const element = await waitForSelectors( | |
[ | |
["aria/Search"], | |
[ | |
"body > div.L3eUgb > div.o3j99.ikrT4e.om7nvf > form > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input", | |
], | |
], | |
targetPage, | |
{ timeout, visible: true } | |
); | |
await scrollIntoViewIfNeeded(element, timeout); | |
const type = await element.evaluate((el) => el.type); | |
if (["select-one"].includes(type)) { | |
await element.select("test"); | |
} else if ( | |
[ | |
"textarea", | |
"text", | |
"url", | |
"tel", | |
"search", | |
"password", | |
"number", | |
"email", | |
].includes(type) | |
) { | |
await element.type("test"); | |
} else { | |
await element.focus(); | |
await element.evaluate((el, value) => { | |
el.value = value; | |
el.dispatchEvent(new Event("input", { bubbles: true })); | |
el.dispatchEvent(new Event("change", { bubbles: true })); | |
}, "test"); | |
} | |
} | |
{ | |
const targetPage = page; | |
const promises = []; | |
promises.push(targetPage.waitForNavigation()); | |
await targetPage.keyboard.down("Enter"); | |
await Promise.all(promises); | |
await targetPage.screenshot({ | |
path: path.join("C:\\ss", "google.png"), | |
type: "png", | |
fullPage: true, | |
}); | |
} | |
await browser.close(); | |
async function waitForSelectors(selectors, frame, options) { | |
for (const selector of selectors) { | |
try { | |
return await waitForSelector(selector, frame, options); | |
} catch (err) { | |
console.error(err); | |
} | |
} | |
throw new Error( | |
"Could not find element for selectors: " + JSON.stringify(selectors) | |
); | |
} | |
async function scrollIntoViewIfNeeded(element, timeout) { | |
await waitForConnected(element, timeout); | |
const isInViewport = await element.isIntersectingViewport({ threshold: 0 }); | |
if (isInViewport) { | |
return; | |
} | |
await element.evaluate((element) => { | |
element.scrollIntoView({ | |
block: "center", | |
inline: "center", | |
behavior: "auto", | |
}); | |
}); | |
await waitForInViewport(element, timeout); | |
} | |
async function waitForConnected(element, timeout) { | |
await waitForFunction(async () => { | |
return await element.getProperty("isConnected"); | |
}, timeout); | |
} | |
async function waitForInViewport(element, timeout) { | |
await waitForFunction(async () => { | |
return await element.isIntersectingViewport({ threshold: 0 }); | |
}, timeout); | |
} | |
async function waitForSelector(selector, frame, options) { | |
if (!Array.isArray(selector)) { | |
selector = [selector]; | |
} | |
if (!selector.length) { | |
throw new Error("Empty selector provided to waitForSelector"); | |
} | |
let element = null; | |
for (let i = 0; i < selector.length; i++) { | |
const part = selector[i]; | |
if (element) { | |
element = await element.waitForSelector(part, options); | |
} else { | |
element = await frame.waitForSelector(part, options); | |
} | |
if (!element) { | |
throw new Error("Could not find element: " + selector.join(">>")); | |
} | |
if (i < selector.length - 1) { | |
element = ( | |
await element.evaluateHandle((el) => | |
el.shadowRoot ? el.shadowRoot : el | |
) | |
).asElement(); | |
} | |
} | |
if (!element) { | |
throw new Error("Could not find element: " + selector.join("|")); | |
} | |
return element; | |
} | |
async function waitForElement(step, frame, timeout) { | |
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); | |
}, timeout); | |
} | |
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 (!Array.isArray(selector)) { | |
selector = [selector]; | |
} | |
if (!selector.length) { | |
throw new Error("Empty selector provided to querySelectorAll"); | |
} | |
let elements = []; | |
for (let i = 0; i < selector.length; i++) { | |
const part = selector[i]; | |
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 []; | |
} | |
if (i < selector.length - 1) { | |
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; | |
} | |
} | |
return elements; | |
} | |
async function waitForFunction(fn, timeout) { | |
let isActive = true; | |
setTimeout(() => { | |
isActive = false; | |
}, timeout); | |
while (isActive) { | |
const result = await fn(); | |
if (result) { | |
return; | |
} | |
await new Promise((resolve) => setTimeout(resolve, 100)); | |
} | |
throw new Error("Timed out"); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment