// This is a "PandaScript", a javascript intended to be run with lightpanda, // e.g. https://lightpanda.io/docs/usage/pandascript, // lightpanda agent ./sanity-check-sites.js const page = new Page(); function mkSelText(sel) { return { selector: sel, fields: { text: '', } } } function assert(condition, statement) { if (!!condition) { return } throw new Error(statement); } // git.awl.red console.log('testing *.awl.red sites and any other maintained through git.awl.red') console.log('testing git.awl.red') await page.goto("https://git.awl.red/~neallred"); const dataGit = page.extract({ title: "title", repos: [mkSelText("h2 a")], }) const seenRepos = { pad: false, astr: false, cli: false, recipes: false, lilgit: false, } assert(dataGit.title === 'neallred repos', 'unexpected title: ' + dataGit.title) for (const repo of dataGit.repos) { seenRepos[repo.text] = true; } const unseen = Object.entries(seenRepos).filter(([_,v]) => !v).map(([k,_]) => k) if (unseen.length > 0) { console.log('did not find the following repos:', unseen.join(', ')) throw new Error(""); } // astr.awl.red console.log('testing astr.awl.red') await page.goto("https://astr.awl.red"); const dataAstr = page.extract({ title: "title", h1: mkSelText('h1'), links: [{ selector: "a", fields: { href: { attr: "href" }, text: '', } }], }) assert(dataAstr.title === 'astr.awl.red', 'unexpected title') assert(dataAstr.h1.text === 'astr.awl.red', 'unexpected title: ' + dataAstr.h1.text) assert(dataAstr.links.length >= 50, 'expected at least 50 astr blog entries: ' + dataAstr.links.length) await page.goto(dataAstr.links[0].href) const dataAstrEntry = page.extract({ title: "title", h1: mkSelText('h1'), p1: mkSelText('p'), }) assert(dataAstrEntry.title === dataAstr.links[0].text, 'expected ' + dataAstr.links[0].text + ", got " + dataAstrEntry.title) assert(dataAstrEntry.h1.text === dataAstr.links[0].text, 'expected ' + dataAstr.links[0].text + ", got " + dataAstrEntry.h1.text) assert(dataAstrEntry.p1.text.length >= 40, 'expected blog paragraph to be at least 40 characters') // recipes.awl.red console.log('testing recipes.awl.red') await page.goto('https://recipes.awl.red'); await page.fill('input[placeholder=search]', 'Tiny Crumb'); await page.waitForState("networkidle"); const dataRecipes = page.extract({ title: "title", h1: mkSelText('h1'), navLinks: [{ selector: "nav details a", fields: { href: { attr: "href" }, text: '', } }], recipes: [{ selector: '#recipes-mount > li', fields: { text: '', } }] }) assert(dataRecipes.navLinks.some(x => x.text === 'Recipes'), 'expected recipes to have nav link to recipes') assert(dataRecipes.navLinks.some(x => x.text === 'Log in'), 'expected recipes to have nav link to log in') assert(dataRecipes.navLinks.some(x => x.text === 'Sign up'), 'expected recipes to have nav link to sign up') page.click('a[href^="/recipes/"]'); dataRecipesTinyCrumb = page.extract({ title: "title", h1: mkSelText('h1'), ingredients: mkSelText('#ingredients'), instructions: mkSelText('#instructions'), about: mkSelText('#about'), }) assert(dataRecipesTinyCrumb.title === 'Tiny Crumbs/Crunchy Pancakes (homemade grape nuts)', 'did not find tiny crumb title: ' + dataRecipesTinyCrumb.title) assert(dataRecipesTinyCrumb.h1.text === 'Tiny Crumbs/Crunchy Pancakes (homemade grape nuts)', 'did not find tiny crumb h1: ' + dataRecipesTinyCrumb.h1.text) assert(dataRecipesTinyCrumb.ingredients.text === 'Ingredients', 'did not find Ingredients section') assert(dataRecipesTinyCrumb.instructions.text === 'Instructions', 'did not find Instructions section') assert(dataRecipesTinyCrumb.about.text === 'About', 'did not find About section') // TODO: Couldn't seem to get the reading env vars part to work // console.log('1') // await page.goto("https://recipes.awl.red/login") // console.log('2') // await page.fill({ selector: 'input[name="username"]', value: "$LP_RECIPES_USER" }) // await page.click('nav summary') // console.log('3') // const withFilled = page.extract({ // userInput: { // selector: 'input[name="username"]', // fields: { // value: { attr: 'value' }, // text: '', // } // } // }) // if (withFilled.userInput.value !== '') { // console.log(JSON.stringify(withFilled.userInput)) // console.log("recipes user auth provided, attempting auth portion of assertions: ", withFilled.userInput.value ) // page.fill('input[name="password"]', "$LP_RECIPES_PASS") // page.click('input[type="submit"]') // await page.waitForState("networkidle"); // const dataRecipesAuthed = page.extract({ // navLinks: [{ // selector: "nav details a", // fields: { // href: { attr: "href" }, // text: '', // } // }], // }) // console.log(dataRecipesAuthed.navLinks.map(x => x.text).join('\n') ) // } console.log('sanity check passed')