【问题标题】:NodeJS Selenium WebDriver for Linux Chrome Docker Image适用于 Linux Chrome Docker 映像的 NodeJS Selenium WebDriver
【发布时间】:2022-02-23 11:18:23
【问题描述】:

在我的一生中,我无法弄清楚如何创建一个轻量级的 Linux 容器,它使用 Selenium WebDriver、Chrome 和 NodeJS 对网站执行测试。启动 ChromeDriver 时,我似乎一直遇到权限问题。

我还希望使用自动更新 ChromeDriver 的软件包,或者 - 也可以锁定 Chrome 以防止自动更新。

我不想运行 Selenium Grid - 只需要一个简单、轻量级的容器。

Dockerfile

# Use alpine-based NodeJS base image
FROM node:latest

#USER root

# Install latest stable Chrome
# https://gerg.dev/2021/06/making-chromedriver-and-chrome-versions-match-in-a-docker-image/
RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | \
    tee -a /etc/apt/sources.list.d/google.list && \
    wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | \
    apt-key add - && \
    apt-get update && \
    apt-get install -y google-chrome-stable libxss1

# Determine major browser version
ARG BROWSER_MAJOR=$(google-chrome --version | sed 's/Google Chrome \([0-9]*\).*/\1/g')

# Install the Chromedriver version that corresponds to the installed major Chrome version
# https://blogs.sap.com/2020/12/01/ui5-testing-how-to-handle-chromedriver-update-in-docker-image/
RUN google-chrome --version | grep -oE "[0-9]{1,10}.[0-9]{1,10}.[0-9]{1,10}" > /tmp/chromebrowser-main-version.txt
RUN wget --no-verbose -O /tmp/latest_chromedriver_version.txt https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$(cat /tmp/chromebrowser-main-version.txt)
RUN wget --no-verbose -O /tmp/chromedriver_linux64.zip https://chromedriver.storage.googleapis.com/$(cat /tmp/latest_chromedriver_version.txt)/chromedriver_linux64.zip && rm -rf /opt/selenium/chromedriver && unzip /tmp/chromedriver_linux64.zip -d /opt/selenium && rm /tmp/chromedriver_linux64.zip && mv /opt/selenium/chromedriver /opt/selenium/chromedriver-$(cat /tmp/latest_chromedriver_version.txt) && chmod 755 /opt/selenium/chromedriver-$(cat /tmp/latest_chromedriver_version.txt) && ln -fs /opt/selenium/chromedriver-$(cat /tmp/latest_chromedriver_version.txt) /usr/bin/chromedriver

# Set the variable for the container working directory
ARG WORK_DIRECTORY=/program

# Create app directory
RUN mkdir -p $WORK_DIRECTORY
WORKDIR $WORK_DIRECTORY

# Install npm packages (do this AFTER setting the working directory)
RUN npm config set unsafe-perm true
RUN npm i selenium-webdriver
ENV NODE_ENV=development NODE_PATH=$WORK_DIRECTORY

# Copy script to execute to working directory
COPY runtest.js .

EXPOSE 8080

# Execute the script in NodeJS
CMD ["node", "runtest.js"]

runtest.js

const { Builder } = require('selenium-webdriver');
const { Options } = require('selenium-webdriver/chrome');

(async function hello() {
    //Browser Setup
    let builder = new Builder().forBrowser('chrome');
    let options = new Options();
    options.headless();                             // run headless Chrome
    options.excludeSwitches(['enable-logging']);    // disable 'DevTools listening on...'
    const driver = await builder.setChromeOptions(options).build();

    console.log('Hello World!');
})();

构建和运行此映像时我当前的错误是:

/program/node_modules/selenium-webdriver/lib/error.js:522

    let err = new ctor(data.message)

              ^


WebDriverError: unknown error: Chrome failed to start: crashed.

  (unknown error: DevToolsActivePort file doesn't exist)

  (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

    at Object.throwDecodedError (/program/node_modules/selenium-webdriver/lib/error.js:522:15)

    at parseHttpResponse (/program/node_modules/selenium-webdriver/lib/http.js:548:13)

    at Executor.execute (/program/node_modules/selenium-webdriver/lib/http.js:474:28)

【问题讨论】:

  • 嗨,西蒙,为什么不使用独立的 chrome?我通常使用两个容器,一个用于 selenium,另一个用于独立 chrome。然后,您可以在代码中使用远程驱动程序而不是本地驱动程序。希望有帮助
  • 嗨,我不需要对 Selenium 运行,我只需要使用 chromedriver 执行一些自动化测试。我试图保持这个设置非常简单。在本地,它工作正常,但是当我将它打包到容器中时,Chromedriver 权限出现问题。
  • 嗨,@Simon 能否提供您尝试过的当前 docker 解决方案和您的自动化测试代码,以便我们确定 Chromedriver 问题以便能够提供帮助
  • 感谢您的帮助!本质上,我的 Dockerfile 旨在 1) 使用最新的 NodeJS 映像,2) 安装最新的稳定版 Chrome,3) 安装最新的相应 chromedriver,4) 安装 npm 包,以及 5) 执行一个简单的脚本。我将编辑帖子以显示文件。

标签: node.js docker selenium selenium-webdriver webdriver


【解决方案1】:

添加--no-sandbox 开关解决了这个问题。从安全的角度来看,我意识到这是不可取的;但是,我控制容器以及它会发生什么,所以我至少认为这是一条合理的路径。如果有其他建议可以解决我原来帖子中的错误,请告诉我。如果Dockerfile 中的任何内容特别可以修剪或修改为更好,还请告知。

回顾一下我想要实现的目标:

  1. 从基础 NodeJS 容器开始。我选择了基于 alpine 的 node:latest 图像。
  2. 安装最新的稳定版 Chrome。
  3. 安装与已安装的主要 Chrome 版本对应的 Chromedriver 版本。
  4. 安装必要的 npm 依赖项。就我而言,那只是selenium-webdriver。我在我的 Dockerfile 中这样做了,但是如果我有更多的依赖项,我会设置一个 package.json 文件,然后在 中运行 npm i Dockerfile.
  5. 执行一个简单的基于 NodeJS 的 Selenium 测试以导航到网页、查找元素并将有关它的信息记录到控制台。

Dockerfile

# 1) Use alpine-based NodeJS base image
FROM node:latest

# 2) Install latest stable Chrome
# https://gerg.dev/2021/06/making-chromedriver-and-chrome-versions-match-in-a-docker-image/
RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | \
    tee -a /etc/apt/sources.list.d/google.list && \
    wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | \
    apt-key add - && \
    apt-get update && \
    apt-get install -y google-chrome-stable libxss1

# 3) Install the Chromedriver version that corresponds to the installed major Chrome version
# https://blogs.sap.com/2020/12/01/ui5-testing-how-to-handle-chromedriver-update-in-docker-image/
RUN google-chrome --version | grep -oE "[0-9]{1,10}.[0-9]{1,10}.[0-9]{1,10}" > /tmp/chromebrowser-main-version.txt
RUN wget --no-verbose -O /tmp/latest_chromedriver_version.txt https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$(cat /tmp/chromebrowser-main-version.txt)
RUN wget --no-verbose -O /tmp/chromedriver_linux64.zip https://chromedriver.storage.googleapis.com/$(cat /tmp/latest_chromedriver_version.txt)/chromedriver_linux64.zip && rm -rf /opt/selenium/chromedriver && unzip /tmp/chromedriver_linux64.zip -d /opt/selenium && rm /tmp/chromedriver_linux64.zip && mv /opt/selenium/chromedriver /opt/selenium/chromedriver-$(cat /tmp/latest_chromedriver_version.txt) && chmod 755 /opt/selenium/chromedriver-$(cat /tmp/latest_chromedriver_version.txt) && ln -fs /opt/selenium/chromedriver-$(cat /tmp/latest_chromedriver_version.txt) /usr/bin/chromedriver

# 4) Set the variable for the container working directory & create the working directory
ARG WORK_DIRECTORY=/program
RUN mkdir -p $WORK_DIRECTORY
WORKDIR $WORK_DIRECTORY

# 5) Install npm packages (do this AFTER setting the working directory)
RUN npm config set unsafe-perm true
RUN npm i selenium-webdriver
ENV NODE_ENV=development NODE_PATH=$WORK_DIRECTORY

# 6) Copy script to execute to working directory
COPY runtest.js .

EXPOSE 8080

# 7) Execute the script in NodeJS
CMD ["node", "runtest.js"]

runtest.js

const { Builder, By } = require('selenium-webdriver');
const { Options } = require('selenium-webdriver/chrome');

(async function hello() {
    let driver;

    try {
        //Browser Setup
        let builder = new Builder().forBrowser('chrome');
        let options = new Options();
        options.headless();                             // run headless Chrome
        options.excludeSwitches(['enable-logging']);    // disable 'DevTools listening on...'
        options.addArguments(['--no-sandbox']);         // not an advised flag but eliminates "DevToolsActivePort file doesn't exist" error.
        driver = await builder.setChromeOptions(options).build();

        // Navigate to Google and get the "Google Search" button text.
        await driver.get('https://www.google.com');
        const btnText = await driver.findElement(By.name('btnK')).getAttribute('value');
        console.log(`Google button text: ${btnText}`);
    } catch (e) {
        console.log(e);
    } finally {
        if (driver) {
            await driver.close();   // helps chromedriver shut down cleanly and delete the "scoped_dir" temp directories that eventually fill up the harddrive.
            await driver.quit();
        }
    }
})();

执行docker build -t "node-chrome" -f Dockerfile .:

在 Docker Desktop 中运行图像会显示按钮文本:

这表明此设置有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 2014-07-04
    • 2021-04-13
    • 2015-02-11
    • 1970-01-01
    • 2018-06-05
    相关资源
    最近更新 更多