Create a standalone desktop app with puppeteer example.
- Run
npm i - Run
node app
For run this example without installation, run in console:
npx https://gist.github.com/ilio/6f4239b60b84a918ab500e2e0528c094
Create a standalone desktop app with puppeteer example.
npm inode appFor run this example without installation, run in console:
npx https://gist.github.com/ilio/6f4239b60b84a918ab500e2e0528c094
| #!/usr/bin/env node | |
| const puppeteer = require('puppeteer'); | |
| const devtools = true; | |
| const indexUrl = 'file:///' + __dirname.replace(/\\/g, '/') + '/index.html'; | |
| const args = [ | |
| // '--start-maximized', | |
| '--disable-infobars', | |
| '--disable-default-apps', | |
| '--disable-popup-blocking', | |
| '--enable-local-file-accesses', | |
| '--allow-file-access-from-files', | |
| '--app=' + indexUrl | |
| ]; | |
| puppeteer.launch({headless: false, devtools, args}).then(async browser => { | |
| let page; | |
| const pages = await browser.pages(); | |
| for (const p of pages) { | |
| const url = await p.url(); | |
| console.log(url); | |
| if (url === indexUrl) { | |
| page = p; | |
| } | |
| } | |
| if (!page) { | |
| console.error('ui page not found', indexUrl); | |
| process.exit(1); | |
| } | |
| await page._client.send('Emulation.clearDeviceMetricsOverride'); | |
| let headlessBrowser; | |
| await page.exposeFunction('sendMessage', async message => { | |
| console.log('message', message); | |
| switch (message.action) { | |
| case 'open-browser': { | |
| headlessBrowser = await puppeteer.launch({headless: true}); | |
| return; | |
| } | |
| case 'new-page': { | |
| const page = await headlessBrowser.newPage(); | |
| const pages = await headlessBrowser.pages(); | |
| return {pageId: pages.length - 1}; | |
| } | |
| case 'pages': { | |
| const pages = await headlessBrowser.pages(); | |
| return {pages: pages.length}; | |
| } | |
| case 'screenshot': { | |
| const pages = await headlessBrowser.pages(); | |
| return await pages[message.pageId].screenshot(); | |
| } | |
| case 'goto': { | |
| const pages = await headlessBrowser.pages(); | |
| await pages[message.pageId].goto(message.url); | |
| return; | |
| } | |
| default: { | |
| return {error: 'Invalid action: ' + message.action}; | |
| } | |
| } | |
| }); | |
| await page.evaluate(() => { | |
| window.onLoaded(); | |
| }); | |
| }); |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>PuppeApp</title> | |
| <script src="index.js"></script> | |
| </head> | |
| <body> | |
| PuppeApp loading | |
| </body> | |
| </html> |
| function screenShootToUrl(screenshot) { | |
| const blob = new Blob([Uint8Array.from(screenshot.data)], {type: 'image/png'}); | |
| return URL.createObjectURL(blob); | |
| } | |
| function clear(node) { | |
| while (node.firstChild) { | |
| node.removeChild(node.firstChild); | |
| } | |
| } | |
| const onLoaded = async () => { | |
| clear(document.body); | |
| const send = (message) => { | |
| console.log('send', message); | |
| return sendMessage(message); | |
| }; | |
| console.log('on open'); | |
| await send({ | |
| action: 'open-browser' | |
| }); | |
| const pages = await send({ | |
| action: 'pages' | |
| }); | |
| let pageId; | |
| if (pages < 1) { | |
| ({pageId} = await send({ | |
| action: 'new-page' | |
| })); | |
| } else { | |
| pageId = 0; | |
| } | |
| let screenshot = await send({ | |
| action: 'screenshot', | |
| pageId | |
| }); | |
| const image = new Image(); | |
| image.src = screenShootToUrl(screenshot); | |
| document.body.appendChild(image); | |
| await send({ | |
| action: 'goto', | |
| url: 'https://pptr.dev/', | |
| pageId | |
| }); | |
| screenshot = await send({ | |
| action: 'screenshot', | |
| pageId | |
| }); | |
| image.src = screenShootToUrl(screenshot); | |
| await new Promise(r => setTimeout(r, 3000)); | |
| screenshot = await send({ | |
| action: 'screenshot', | |
| pageId | |
| }); | |
| image.src = screenShootToUrl(screenshot); | |
| }; | |
| window.onLoaded = onLoaded; | |
| /** | |
| * @callback sendMessage | |
| * @param {{action:String}} message | |
| */ |
| { | |
| "name": "puppe-app", | |
| "version": "1.0.0", | |
| "description": "", | |
| "main": "app.js", | |
| "bin": "./app.js", | |
| "scripts": { | |
| "test": "echo \"Error: no test specified\" && exit 1" | |
| }, | |
| "author": "", | |
| "license": "ISC", | |
| "dependencies": { | |
| "puppeteer": "^1.6.2" | |
| } | |
| } |