What is Selenium | | connect to VNC through the web browser | Search

This code snippet sets up and manages a Selenium server using Docker, ensuring a clean and consistent environment by removing existing containers and building a new one. It utilizes Docker to manage the server and returns a promise for asynchronous handling of the setup process.

Run example

npm run import -- "What is Selenium"

What is Selenium

var importer = require('../Core');
var path = require('path');
var fs = require('fs');
var execCmd = importer.import("spawn child process");
var importer = require('../Core');
var seleniumDocker = importer.import("selenium docker");

var DOWNLOAD_DIR = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || '', 'Downloads');
var PROFILE_DIR = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || '', '.defaultProfile');
var DOCKERFILE = path.resolve(path.join(__dirname, 'Dockerfile'));

function getSeleniumServer(name = 'act-selenium') {
    try {
        fs.mkdirSync(DOWNLOAD_DIR);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    try {
        fs.mkdirSync(PROFILE_DIR);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    try {
        fs.unlinkSync(path.join(PROFILE_DIR, 'SingletonLock'));
    } catch (err) {
        if (err.code != 'ENOENT') {
            throw err;
        }
    }
    seleniumDocker(DOCKERFILE);
    return execCmd('docker ps -a')
        .then(r => {
            if (r[0].indexOf(name) > -1) {
                return execCmd('docker stop ' + name)
                    .then(r => new Promise(resolve =>
                        setTimeout(() => resolve(r), 1000)))
                    .then(() => execCmd('docker rm ' + name));
            }
        })
        .then(() => new Promise(resolve =>
            setTimeout(() => resolve(), 1000)))
        .then(() => {
            var build = 'docker build -t ' + name + ' "'
                + path.dirname(DOCKERFILE) + '"\n'
                + 'docker run --shm-size=3g -d '
                + '--name ' + name + ' '
                + '-p 8888:8888 '
                + '-p 6080:6080 '
                + '-p 5900:5900 '
                + '-p 4444:4444 '
                + '-p 4200:4200 '
                + '-p 3000:3000 '
                // TODO: add profile dir back in when permissions works on windows
                + '-v "' + DOWNLOAD_DIR + '":/data/downloads '
                + name + '\n';
            return execCmd(build)
        })
        .then(r => new Promise(resolve => setTimeout(() => resolve(r), 6000)))
};
module.exports = getSeleniumServer;

if(typeof $ !== 'undefined') {
    $.async();
    getSeleniumServer()
        .then(r => $.sendResult(r))
        .catch(e => $.sendError(e));
}

What the code could have been:

const path = require('path');
const fs = require('fs');
const { spawn } = require('child_process');
const importer = require('../Core');
const seleniumDocker = importer.import('selenium docker');

const DOWNLOAD_DIR = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, 'Downloads');
const PROFILE_DIR = path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, '.defaultProfile');
const DOCKERFILE = path.resolve(path.join(__dirname, 'Dockerfile'));

async function getSeleniumServer(name = 'act-selenium') {
  // Create download and profile directories if they don't exist
  await Promise.all([
    fs.mkdir(DOWNLOAD_DIR, { recursive: true }),
    fs.mkdir(PROFILE_DIR, { recursive: true }),
  ]);

  // Remove SingletonLock file if it exists
  try {
    await fs.unlink(path.join(PROFILE_DIR, 'SingletonLock'));
  } catch (err) {
    if (err.code!== 'ENOENT') {
      throw err;
    }
  }

  // Stop and remove existing container if it exists
  const containers = await getDockerContainers();
  if (containers.some(container => container.Name === name)) {
    await stopAndRemoveContainer(name);
  }

  // Build and run a new container
  const build = `docker build -t ${name} "${path.dirname(DOCKERFILE)}"\n` +
    `docker run --shm-size=3g -d --name ${name} -p 8888:8888 -p 6080:6080 -p 5900:5900 -p 4444:4444 -p 4200:4200 -p 3000:3000 -v "${DOWNLOAD_DIR}":/data/downloads ${name}\n`;
  await execCmd(build);

  // Wait for the container to start
  await new Promise(resolve => setTimeout(() => resolve(), 6000));
}

async function getDockerContainers() {
  const output = await execCmd('docker ps -a');
  return output.split('\n').map(line => JSON.parse(line));
}

async function stopAndRemoveContainer(name) {
  await execCmd(`docker stop ${name}`);
  await new Promise(resolve => setTimeout(() => resolve(), 1000));
  await execCmd(`docker rm ${name}`);
}

function execCmd(cmd) {
  return new Promise((resolve, reject) => {
    spawn(cmd, { shell: true })
     .on('close', code => {
        if (code === 0) {
          resolve();
        } else {
          reject(new Error(`Command failed with code ${code}`));
        }
      })
     .on('error', err => reject(err));
  });
}

module.exports = getSeleniumServer;

if (typeof $!== 'undefined') {
  $.async();
  getSeleniumServer()
   .then(r => $.sendResult(r))
   .catch(e => $.sendError(e));
}

This code snippet sets up and manages a Selenium server using Docker.

Here's a breakdown:

  1. Imports:

  2. Constants:

  3. getSeleniumServer Function:

Overall Logic: