I have a simple WebdriverIO project with a few test cases. I run everything "locally" (no CI
variable declared according my wdio.conf.js
settings) with browserName: "chrome"
in headless mode, and Mocha
test runner.
Now, I'm trying to run exactly the same test cases against a Selenium server (started via Docker), but all tests cases fail with this little error message: Timeout of 15000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
If I go to the Selenium Web console I can see the sessions being created and deleted, so the configuration should be OK.
// wdio.conf.js
const cfg = require("config");
const fs = require("fs");
const path = require("path");
const source = { };
if (process.env.CI) { // ...if running on a CI/CD environment
source.hostname = "localhost";
source.maxInstances = 5;
source.path = "/wd/hub";
source.port = 4444;
source.services = ["selenium-standalone"];
} else {
source.filesToWatch = [];
}
exports.config = Object.assign({}, {
runner: "local",
bail: 0,
baseUrl: cfg.get("baseUrl"),
coloredLogs: true,
exclude: [
// "test/spec/**.spec.ts",
],
filesToWatch: [],
hostname: "localhost",
logLevel: "warn", // trace | debug | info | warn | error | silent
maxInstances: 1,
outputDir: `${__dirname}/logs/`,
path: "/",
port: 9515,
specs: ["./test/**/*",],
sync: true,
waitforTimeout: 25000,
framework: "mocha",
specFileRetries: 0,
mochaOpts: {
require: ["tsconfig-paths/register"],
timeout: 15000,
ui: "bdd",
},
capabilities: [
{
browserName: "chrome",
maxInstances: 5,
"goog:chromeOptions": {
args: [
"--disable-gpu",
"--headless",
"--no-sandbox",
"--test-type",
],
},
},
],
reporters: ["spec",],
services: ["chromedriver",],
before: function (capabilities, specs) {
require("ts-node").register({ files: true, transpileOnly: true });
},
// ...Cucumber specific hooks
}, source);
Moreover, I disabled all test cases and put something simple like this:
browser.url(`https://duckduckgo.com/`);
$("#search_form_input_homepage").setValue("webdriverio");
$("#search_button_homepage").click();
const expected: string = "WebdriverIO · Next-gen WebDriver test framework for Node.js";
expect($("div#r1-0 h2.result__title a.result__a").getText()).to.contain(expected);
...and still, the same error message >:(
Any clues?
TL;DR — define/set proxy settings at the container level.
OK, it was a silly detail: we use a corporate proxy.
My initial thoughts was to try setting the proxy info (at the browser level) in wdio.conf.js
:
capabilities: [
{
browserName: "chrome",
maxInstances: 5,
"goog:chromeOptions": {
args: [
"--disable-gpu",
"--headless",
// "--no-sandbox",
"--test-type",
// "--window-size=1024x768",
],
},
proxy: {
httpProxy: "http://corporate.proxy:9080",
noProxy: ["127.0.0.1", "localhost", ".domain.tld",],
proxyType: "manual",
sslProxy: "http://corporate.proxy:9080",
},
},
],
...but that didn't work, so I ended up setting that at container level (in the Docker Compose file):
version: "3.7"
services:
chrome:
container_name: standalone-chrome
environment:
- CHROME_VERSION=76.0.3809 # ...make sure this is in sync with the chromedriver version in package.json
- HTTPS_PROXY=http://corporate.proxy:9080
- HTTP_PROXY=http://corporate.proxy:9080
- NO_PROXY=127.0.0.1,localhost,.domain.tld
- START_XVFB=false
healthcheck:
interval: 15s
retries: 3
timeout: 30s
test: "/opt/bin/check-grid.sh --host chrome --port 4444"
image: selenium/standalone-chrome:3.141.59-selenium
networks:
- global-network
ports:
- "4444:4444"
networks:
global-network:
driver: bridge
name: selenium-network
Then I can run the tests against that dockerized "standalone" Chrome instance, or in the CI/CD pipeline via: CI=docker npm run test
(mapped in package.json
like: "scripts": { "test": "wdio" }
).
Hope this helps somebody in the future...