Oregami
Repositories/oxedyne/daimond

oxedyne/daimond/dev/shot_mobile.mjs

3.4 KiB, 1 run

created by r2519314175:163, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1// shot_mobile.mjs — capture the phone shell for the eye, not the assertion.
2import { open } from './harness.mjs';
3const sleep = ms => new Promise(r => setTimeout(r, ms));
4
5const s = await open({ signIn: true, connect: true, name: 'mobileshots' });
6const { page } = s;
7// Never let a hung webfont fetch stall document.fonts.ready (and the screenshot).
8await page.route('**/*.{woff,woff2,ttf,otf}', r => r.abort());
9await page.setViewportSize({ width: 390, height: 844 });
10await page.addStyleTag({ content: '*,*::before,*::after{transition:none!important;animation:none!important}' });
11await sleep(300);
12// connectMock leaves the settings modal up; take it down for a clean floor.
13await page.evaluate(() => { try { window.DaimondAdmin.closeModal(); } catch (e) {} const m = document.getElementById('settings-modal'); if (m) m.style.display = 'none'; });
14await sleep(200);
15
16// A started chat, so the floor is a real conversation.
17await page.evaluate(() => { try { document.getElementById('new-session-btn').click(); } catch (e) {} });
18await sleep(300);
19await page.evaluate(() => { const b = [...document.querySelectorAll('button')].find(x => /^Start$/.test(x.textContent.trim())); if (b) b.click(); });
20await sleep(400);
21await page.evaluate(() => {
22 // A couple of turns of copy so the floor reads like a conversation.
23 const out = document.getElementById('chat-output'); if (!out) return;
24 out.insertAdjacentHTML('beforeend',
25 '<div class="chat-msg chat-msg-user"><div class="chat-msg-content">What did the invoice from Acme say?</div></div>' +
26 '<div class="chat-msg chat-msg-assistant"><div class="chat-msg-content">It totals £1,240, due on the 30th. Want me to open it beside us?</div></div>');
27});
28await sleep(200);
29// Playwright's screenshot waits on document.fonts.ready, which never settles
30// here; CDP's captureScreenshot does not, so use it directly.
31import { writeFileSync } from 'node:fs';
32const cdp = await s.browser.newCDPSession(page);
33const shot = async (p) => {
34 try {
35 const { data } = await cdp.send('Page.captureScreenshot', { format: 'png' });
36 writeFileSync(p, Buffer.from(data, 'base64'));
37 console.log('shot ' + p);
38 } catch (e) { console.log('SKIP ' + p + ' — ' + e.message.split('\n')[0]); }
39};
40
41await shot('shots/mobile-1-floor.png');
42
43// The drawer.
44await page.evaluate(() => document.getElementById('drawer-btn').click());
45await sleep(400);
46await shot('shots/mobile-2-drawer.png');
47await page.evaluate(() => document.getElementById('scrim').click());
48await sleep(400);
49
50// A message, risen as a sheet at its half detent — the thing beside the daimon.
51await page.evaluate(() => {
52 const head = document.getElementById('msg-head'), body = document.getElementById('msg-body');
53 if (head) head.innerHTML = '<div class="msg-subject" style="font-weight:600;font-size:16px;margin-bottom:6px">Invoice #4021 — Acme Ltd</div><div style="color:var(--text-muted);font-size:13px">accounts@acme.example · 14 Jul</div>';
54 if (body) body.innerHTML = '<p>Dear customer,</p><p>Please find attached invoice #4021 for services rendered in June, totalling <b>£1,240.00</b>, payable by 30 July.</p><p>Kind regards,<br>Acme Ltd Accounts</p>';
55 window.DaimondPanels.show('msg');
56});
57await sleep(500);
58await shot('shots/mobile-3-sheet-half.png');
59
60// Raised to full for immersive reading.
61await page.evaluate(() => { const g = document.getElementById('msheet-grab'); /* nudge to full via API-free path */ });
62await sleep(100);
63await s.close();
64console.log('done');