github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/webdriver/appserver.js (about)

     1  /**
     2   * Copyright 2019 The WPT Dashboard Project. All rights reserved.
     3   * Use of this source code is governed by a BSD-style license that can be
     4   * found in the LICENSE file.
     5   */
     6  
     7  const { spawn } = require('child_process');
     8  const { debug } = require('debug');
     9  const process = require('process');
    10  
    11  const log = debug('wpt.fyi');
    12  
    13  const ready = Symbol('ready');
    14  
    15  class DevAppserver {
    16    /**
    17     * @typedef {object} DevAppserverConfig
    18     * @property {string} project
    19     * @property {number} port
    20     * @property {number} gcdPort
    21     */
    22    /**
    23     * @param {DevAppserverConfig} config
    24     */
    25    constructor(config) {
    26      this.config = Object.freeze(
    27        Object.assign({
    28          project: 'test-app',
    29          port: 9090,
    30          gcdPort: 9091,
    31        }, config)
    32      );
    33      this.process = startDevAppserver(this.config);
    34      this[ready] = this._awaitReady(this.process);
    35  
    36      /**
    37       * @type {URL} url The URL of the dev_appserver frontend
    38       */
    39      this.url = `http://localhost:${this.config.port}`;
    40    }
    41  
    42    /**
    43     * @type {Promise} ready
    44     */
    45    get ready() {
    46      return this[ready];
    47    }
    48  
    49    _awaitReady(process) {
    50      return new Promise(resolve => {
    51        const logDevAppserver = debug('wpt.fyi:appserver');
    52        process.stderr.on('data', buffer => {
    53          logDevAppserver(buffer.toString());
    54        });
    55  
    56        // TODO(Hexcles): do we still need to check if the server is up?
    57        resolve();
    58      });
    59    };
    60  
    61    close() {
    62      return new Promise(resolve => {
    63        this.process.on('close', () => {
    64          resolve();
    65        });
    66        this.process.kill();
    67      });
    68    }
    69  }
    70  
    71  /**
    72   * Launch a dev_appserver.py subprocess.
    73   *
    74   * @param {object} config
    75   * @returns DevAppserver
    76   */
    77  function launch(config) {
    78    return new DevAppserver(config);
    79  }
    80  
    81  function startDevAppserver(config) {
    82    const child = spawn('./web',
    83        {
    84          cwd: '..',
    85          env: {
    86            PORT: config.port,
    87            DATASTORE_PROJECT_ID: config.project,
    88            DATASTORE_EMULATOR_HOST: `127.0.0.1:${config.gcdPort}`,
    89          },
    90        });
    91    process.on('exit', () => {
    92      log('killing appserver subprocess...');
    93      child.kill();
    94    });
    95    return child;
    96  }
    97  
    98  module.exports = { DevAppserver, launch };