Closed4

PlaywrightのBrowserType#connectとBrowserType#connectOverCDPの違い

Yusuke IwakiYusuke Iwaki

まえおき

ドキュメントはさっぱりわからない。マイクロソフトあるある。

一言でいうと

  • connectはPlaywrightのブラウザサーバーを立てたものにWebSocket接続する
  • connectOverCDPはChromeのremote-debugging-portに直接接続する

spec

connect

https://github.com/microsoft/playwright/blob/master/tests/browsertype-connect.spec.ts

  private async _startRemoteServer(options?: RemoteServerOptions): Promise<RemoteServer> {
    if (this._remoteServer)
      throw new Error('can only start one remote server');
    this._remoteServer = new RemoteServer();
    await this._remoteServer._start(this._browserType, this._browserOptions, options);
    return this._remoteServer;
  }
async function start() {
  const { playwrightPath, browserTypeName, launchOptions, stallOnClose } = JSON.parse(process.argv[2]);
  if (stallOnClose) {
    launchOptions.__testHookGracefullyClose = () => {
      console.log(`(stalled=>true)`);
      return new Promise(() => {});
    };
  }

  const playwright = require(require('path').join(playwrightPath, 'index'));

  const browserServer = await playwright[browserTypeName].launchServer(launchOptions);
  browserServer.on('close', (exitCode, signal) => {
    console.log(`(exitCode=>${exitCode})`);
    console.log(`(signal=>${signal})`);
  });
  console.log(`(pid=>${browserServer.process().pid})`);
  console.log(`(wsEndpoint=>${browserServer.wsEndpoint()})`);
}

launchServerしたものにクライアントとして接続するのがconnect.

connectOverCDP

https://github.com/microsoft/playwright/blob/master/tests/chromium/chromium.spec.ts

単にChromeのremote-debugging-portを指定して接続するだけ。当然Chromeおんりー

Yusuke IwakiYusuke Iwaki

Playwrightサーバー(connectの相手)を建てるには

なんとなくcliでサポートしてそうな気がするのでソースを見てみる。

https://github.com/microsoft/playwright/blob/master/src/cli/driver.ts

export async function runServer(port: number | undefined) {
  const wsEndpoint = await PlaywrightServer.startDefault(port);
  console.log('Listening on ' + wsEndpoint);  // eslint-disable-line no-console
}

export async function launchBrowserServer(browserName: string, configFile?: string) {
  let options: LaunchServerOptions = {};
  if (configFile)
    options = JSON.parse(fs.readFileSync(configFile).toString());
  const browserType = (playwright as any)[browserName] as BrowserType;
  const server = await browserType.launchServer(options);
  console.log(server.wsEndpoint());
}

なんか2つある。

else if (process.argv[2] === 'run-server')
  runServer(process.argv[3] ? +process.argv[3] : undefined);

else if (process.argv[2] === 'launch-server')
  launchBrowserServer(process.argv[3], process.argv[4]).catch(logErrorAndExit);

playwright run-server

https://github.com/microsoft/playwright/pull/6164

かなり最近!開発途中っぽい。「BrowserType単位でサーバーを立てようとすると、Playwrightインスタンスが必要になるよね、」みたいな議論から、Playwright.connectが爆誕しようとしているっぽい。

https://github.com/microsoft/playwright/issues/4687

playwright launch-server

https://github.com/microsoft/playwright/pull/5713

BrowserType.connectの対向先を作るコマンド。まさにこれだ。

Yusuke IwakiYusuke Iwaki

サーバー

$ cat playwright-config.json 
{
  "port": 1234
}

$ npx playwright launch-server chromium playwright-config.json 
ws://127.0.0.1:1234/a359acad5400bdf6fd59ce227dc8f531

クライアント

$ npm init --yes
$ npm install playwright-core
example.js
const playwright = require('playwright-core')

const endpointURL = "ws://127.0.0.1:1234/a359acad5400bdf6fd59ce227dc8f531"
playwright.chromium.connect({ wsEndpoint: endpointURL }).then(async (browser) => {
    const page = await browser.newPage();
    await page.goto('https://github.com/YusukeIwaki')
    await page.screenshot({ path: 'YusukeIwaki.png' })
})
$ node example.js
$ open YusukeIwaki.png

Yusuke IwakiYusuke Iwaki

クライアント側のbrowserTypeは何でもいいみたい。( DEBUG=pw:channel* つきで実行するとわかるが、WebSocket上でPlaywrightプロトコルが流れるだけなので、ほとんどのコマンドではbrowserTypeによる動作差分がないため)

サーバー側がWebKitを起動していれば、クライアントが playwright.chromium.connect で接続したとしてもWebKitでの自動操作となる。

このスクラップは2021/04/20にクローズされました