67b3fd23d1
gates / gates (push) Failing after 13m1s
Part A: claim table documentation/audits/website-refresh-2026-10-08/claims.md; "100% open source" corrected from the licence read; unbacked claims cut (firewall, RAID, snapshots, new-machine restore, self-managed mode, household VPN, "never lost"). Part B: dawarich, docmost, grimmory, homebox, karakeep, mealie, metube, radicale, recipe-importer, sparkyfitness cards; plant-it and wger cut (not offered). Part C: /en/ twins, nav language switch, hreflang both ways, sitemap with xhtml:link, og-image-en.png. Part D: site_gates.py twins/lang/same-apps/no-Hungarian/FAQ-JSON-LD/tail. Operator ruling 9 + choice B in 10-localisation.md §11, §10.7. Register: R-902 (contact mailer source in no repo); R-813, R-784, R-559 annotated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
47 lines
2.9 KiB
JavaScript
47 lines
2.9 KiB
JavaScript
// Recipe Importer screenshots for the website card: on scratch guest 9202, headless Chrome through the box's own
|
|
// traefik, passing the setup gate as the household. No recipe site is contacted (a scraped recipe would be a third
|
|
// party's text and picture). The app's own settings form is saved with an INVENTED Mealie address and a placeholder
|
|
// key (no Mealie exists behind it), which is what opens its import page; the shots are its import and settings pages.
|
|
const puppeteer = require('puppeteer');
|
|
const fs = require('fs');
|
|
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
|
const S = JSON.parse(fs.readFileSync('/out/secrets.json'));
|
|
const D = process.env.DOMAIN, URL = `https://${process.env.SUB}.${D}`;
|
|
const DEMO_URL = 'https://www.example.com/receptek/rakott-krumpli';
|
|
(async () => {
|
|
const b = await puppeteer.launch({args: ['--no-sandbox', '--ignore-certificate-errors', '--lang=hu-HU',
|
|
'--host-resolver-rules=MAP * ' + process.env.TRAEFIK]});
|
|
const p = await b.newPage();
|
|
await p.setCookie({name: 'felhom_session', value: S.session, domain: `felhom.${D}`, path: '/', secure: true});
|
|
await p.setViewport({width: 1280, height: 800});
|
|
await p.goto(URL + '/settings', {waitUntil: 'networkidle2'});
|
|
await sleep(1000);
|
|
const set = async (sel, v) => { const f = await p.$(sel); if (f) { await f.click({clickCount: 3}); await f.type(v); } else console.log('no field', sel); };
|
|
await set('input[name=mealie_url]', 'https://recipes.example.hu');
|
|
await set('input[name=mealie_api_key]', 'demo-placeholder');
|
|
await Promise.all([p.waitForNavigation({waitUntil: 'networkidle2'}).catch(() => {}),
|
|
p.$eval('input[name=mealie_url]', el => el.form.submit())]);
|
|
await sleep(1000);
|
|
console.log('after save', p.url());
|
|
await p.screenshot({path: '/out/settings.png'});
|
|
await p.goto(URL + '/import', {waitUntil: 'networkidle2'});
|
|
await sleep(1500);
|
|
console.log('import ->', p.url());
|
|
const ta = await p.$('textarea, input[type=url], input[name=url]');
|
|
if (ta) await ta.type(DEMO_URL); else console.log('no url field');
|
|
await sleep(500);
|
|
await p.screenshot({path: '/out/import.png'});
|
|
// the bulk tab: several invented addresses at once
|
|
await p.click('::-p-text(Tömeges importálás)').catch(e => console.log('no bulk tab', e.message));
|
|
await sleep(800);
|
|
const bulk = await p.$$('textarea');
|
|
const vis = [];
|
|
for (const t of bulk) if (await t.isVisible()) vis.push(t);
|
|
if (vis.length) await vis[0].type(['https://www.example.com/receptek/rakott-krumpli', 'https://www.example.com/receptek/gulyasleves',
|
|
'https://www.example.com/receptek/turos-csusza', 'https://www.example.com/receptek/meggyes-pite'].join('\n'));
|
|
else console.log('no visible bulk textarea');
|
|
await sleep(500);
|
|
await p.screenshot({path: '/out/bulk.png'});
|
|
await b.close();
|
|
})().catch(e => { console.error(e); process.exit(1); });
|