chromium/docs/webapps/cdp/demo.mjs

import {stdin as input, stdout as output} from 'node:process';
import * as readline from 'node:readline/promises';
import puppeteer from 'puppeteer';
import WebSocket from 'ws';

// Running this test needs a local build with https://crrev.com/c/5532619.
(async () => {
    // Launch the browser and open a new blank page
  const browser = await puppeteer.launch({
    executablePath: 'out/default/chrome'
    headless: false,
    slowMo: 100,
    // Expected to run via WebSocket.
    pipe: false,
  });

  const ws = new WebSocket(browser.wsEndpoint(), {perMessageDeflate: false});
  await new Promise(resolve => ws.once('open', resolve));
  const queue = [];
  var id = 1;

  const send = obj => () => {
    console.log('    >>>> Sending: ' + JSON.stringify(obj));
    ws.send(JSON.stringify({id: id, ...obj}));
  };

  const show_apps =
      () => async () => {
        console.log('**** Now I will show the chrome://apps');
        const page = await browser.newPage();
        await page.goto('chrome://apps');
        run();
      }

  const run = () => {
    if (queue.length > 0) {
      queue.shift()();
    }
  };

  const waitfor_enter = (msg) => async () => {
    const rl = readline.createInterface({input, output});
    await rl.question('**** ' + msg, ans => {
      rl.close();
    });
    run();
  };

  ws.addEventListener('message', e => {
    console.log('    <<<< Result: ' + e.data);
    const res = JSON.parse(e.data);
    if (res.result && res.result.targetId) {
      queue.unshift(send({
        method: 'Target.attachToTarget',
        params: {targetId: res.result.targetId}
      }));
    }
    if (res.id == id) {
      id++;
      run();
    }
  });

  queue.push(send({
    method: 'PWA.launch',
    params: {
      manifestId: 'https://developer.chrome.com/',
    }
  }));

  queue.push(show_apps());

  queue.push(waitfor_enter(
      'The first launch should fail since the app has not been installed yet. Press enter to move forward.'));

  queue.push(send({
    method: 'PWA.install',
    params: {
      manifestId: 'https://developer.chrome.com/',
      installUrlOrBundleUrl: 'https://developer.chrome.com/'
    }
  }));

  queue.push(send({
    method: 'PWA.launch',
    params: {
      manifestId: 'https://developer.chrome.com/',
    }
  }));

  queue.push(waitfor_enter(
      'The second launch should succeed - press enter to move forward'));

  queue.push(send({
    method: 'PWA.getOsAppState',
    params: {
      manifestId: 'https://developer.chrome.com/',
    }
  }));

  // Does not work - it needs a WebSocket connecting to the page.
  queue.push(send({
    method: 'Page.getAppManifest',
    params: {
      manifestId: 'https://developer.chrome.com/',
    }
  }));

  queue.push(show_apps());

  queue.push(waitfor_enter('Press enter to uninstall the web app.'));

  queue.push(send({
    method: 'PWA.uninstall',
    params: {
      manifestId: 'https://developer.chrome.com/',
    }
  }));

  queue.push(
      waitfor_enter('Press enter to close the browser window and stop.'));

  queue.push(() => {
    if (queue.length > 0) {
      throw new Error('The queue should be empty now.')
    }
    browser.close();
    process.exit();
  });

  run();
})();