Created
September 6, 2019 18:17
-
-
Save JpOnline/e24c5ec870ff935a98459ca6546c6dd6 to your computer and use it in GitHub Desktop.
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
// General e2e test that click random things in a page checking the | |
// events and state of a Re-Frame app. | |
// | |
// To Run | |
// npm i puppeteer | |
// node puppeteer-clicking-randomly.js | |
const puppeteer = require('puppeteer'); | |
var fs = require('fs'); | |
const TIMESTOCLICK = 30 | |
async function createDir(){ | |
const now = new Date() | |
const dir = './' + now.getFullYear() + "-" | |
+ (now.getMonth() + 1) + "-" | |
+ now.getDate() + "_" | |
+ now.getHours() + "-" | |
+ now.getMinutes() + "-" | |
+ now.getSeconds(); | |
if (!fs.existsSync(dir)){ | |
fs.mkdirSync(dir); | |
} | |
return dir | |
} | |
async function hideReFrame10xSidePanel(page){ | |
await page.keyboard.down('Control'); | |
await page.keyboard.press('KeyH'); | |
await page.keyboard.up('Control'); | |
} | |
async function takeFullPageScreenshot(page, filePath){ | |
const bodyHandle = await page.$('body'); | |
const { width, height } = await bodyHandle.boundingBox(); | |
await page.screenshot({ | |
clip: { | |
x: 0, | |
y: 0, | |
width, | |
height | |
}, | |
path: filePath | |
}); | |
await bodyHandle.dispose(); | |
} | |
function redefineReFrameEventHandler() { | |
const temp = window.re_frame.events.handle.bind({}) | |
window.re_frame.events.handle = reFrameEvent => { | |
window.pptr_i = window.pptr_i + 1 | 0 | |
window.pptr_event = reFrameEvent | |
return temp(reFrameEvent); | |
} | |
} | |
async function reportDifferenceInAppState(page, appendToReport, mainFn){ | |
// Keep the app-state | |
await page.evaluate('window.pptr_stateBefore = window.pptr_stateAfter || window.re_frame.db.app_db.state'); | |
await mainFn() | |
// Difference from the last 2 app-states | |
await page.evaluate('window.pptr_stateAfter = window.re_frame.db.app_db.state'); | |
const stateDiff = await page.evaluate(() => { | |
return cljs.core.clj__GT_js.call( | |
null,cljs.core.zipmap.call( | |
null,new cljs.core.PersistentVector(null, 2, 5, | |
cljs.core.PersistentVector.EMPTY_NODE, [ | |
new cljs.core.Keyword(null,"before","before",-1633692388), | |
new cljs.core.Keyword(null,"after","after",594996914) | |
], null), | |
cljs.core.butlast.call( | |
null,clojure.data.diff.call(null, | |
window.pptr_stateBefore, | |
window.pptr_stateAfter)))); | |
// Equivalent in cljs | |
// (->> (clojure.data/diff %1 %2) | |
// butlast | |
// (zipmap [:before :after]) | |
// clj->js) | |
}); | |
if (stateDiff.before !== null || stateDiff.after !== null){ | |
appendToReport(JSON.stringify(stateDiff, null, 2)) | |
} | |
} | |
async function scrollToElement(page, appendToReport, elementId){ | |
try { | |
await page.hover('#'+elementId) | |
}catch(err){ | |
if ((err.message == 'Node is either not visible or not an HTMLElement' || | |
err.message == 'Node is detached from document')) { | |
appendToReport("Erro ao dar scroll: " + err.message + "\n") | |
} | |
} | |
} | |
function clickRandomElement(newId) { | |
// const testButton = document.querySelector('#teste') | |
// testButton.click() | |
const allElements = []; | |
const blockList = ['#--re-frame-10x--', '#com-rigsomelight-devcards-main > div > div > div.com-rigsomelight-devcards-card-base.com-rigsomelight-devcards-breadcrumbs.com-rigsomelight-devcards-typog', '#hide-all', '#show-all'] | |
const findAllElements = function(nodes) { | |
for (let i = 0, el; el = nodes[i]; ++i) { | |
allElements.push(el); | |
// If the element has a shadow root, dig deeper. | |
if (el.shadowRoot) { | |
findAllElements(el.shadowRoot.querySelectorAll('*')); | |
} | |
} | |
}; | |
findAllElements(document.querySelectorAll('*')); | |
const elems = allElements | |
.filter(el => el.offsetParent !== null) | |
.filter(el => el.onclick !== null) | |
.filter(el => el.localName !== 'a' || el.href !== "#") | |
.filter(el => !isAChildOfABlockedListElement(el)) | |
.filter(el => typeof(el.click) === 'function') | |
const randomElem = elems[Math.floor(Math.random() * elems.length)]; | |
try{ | |
randomElem.click() | |
}catch(err){ | |
return "Erro ao clicar: " + err.message | |
} | |
randomElem.id = newId | |
return [randomElem.localName, randomElem.innerText.replace(/\n/g, "")] | |
function isAChildOfABlockedListElement(el){ | |
for (b of blockList){ | |
let blockedEl = document.querySelector(b) | |
if (blockedEl && blockedEl.contains(el)){ | |
return true | |
} | |
} | |
return false | |
} | |
} | |
(async () => { | |
const browser = await puppeteer.launch({ | |
// headless: false | |
}); | |
const page = await browser.newPage() | |
const url = 'http://localhost:9500/cards.html#!/pr4.prototipo' | |
await page.goto(url) | |
const dir = createDir() | |
const appendToReport = async textToAppend => { | |
fs.appendFileSync((await dir) + "/report.txt", textToAppend); | |
} | |
appendToReport(url + "\n") | |
await hideReFrame10xSidePanel(page) | |
await page.evaluate(redefineReFrameEventHandler); | |
for (let i = 1; i <= TIMESTOCLICK; i++){ | |
await reportDifferenceInAppState(page, appendToReport, async () => { | |
// Used to see if some event was dispatched | |
let eventIndexAfter | |
let eventIndexBefore = eventIndexAfter || await page.evaluate('window.pptr_i') | |
let elementId = "clicked" + i | |
const clickedElement = await page.evaluate(clickRandomElement, elementId) | |
await scrollToElement(page, appendToReport, elementId) | |
appendToReport("\n\n" + elementId + ": " + clickedElement + "\n") | |
console.log(elementId, clickedElement); | |
// Save screenshot every 10 clicks | |
if (i % 10 == 0){ | |
await page.screenshot({path: await dir + '/' + elementId + '.png'}); | |
} | |
if (i % 20 == 1){ | |
await takeFullPageScreenshot(page, await dir + '/' + elementId + '_fullpage.png') | |
} | |
// await page.waitFor(1000) | |
// Used to see if some event was dispatched | |
eventIndexAfter = await page.evaluate('window.pptr_i') | |
// Append event to the report file only if an event was dispatched | |
if (eventIndexBefore !== eventIndexAfter){ | |
let lastEvent = await page.evaluate('cljs.core.clj__GT_js.call(null, window.pptr_event)') | |
appendToReport("Evento: " + lastEvent + "\n") | |
console.log("Evento", lastEvent) | |
} | |
}) | |
} | |
await browser.close() | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment