I am running my whole system using docker-compose and I am trying to execute my end-to-end tests (written with Nightwatch) using a selenium/chrome service that is in the same network. My frontend is VueJS and the image is built from a node base image. I am running the tests with docker-compose exec frontend npm run test-selenium and getting the following output:
> [email protected] test-selenium
> nightwatch -c nightwatch-selenium.conf.js
[Login Test] Test Suite
──────────────────────────────────────────────
ℹ Connected to chrome on port 4444 (1494ms).
Using: chrome (102.0.5005.61) on LINUX.
Running login:
───────────────────────────────────────────────────────────────────────────────────────────────────
ℹ Loaded url http://frontend:8090/login in 2049ms
NoSuchElementError: An error occurred while running .click() command on <Element [name=@loginBt]>: Timed out while waiting for element "#loginBt" with "css selector" to be present for 5000 milliseconds.
at Object.login (/app/tests/loginTest.js:8:8)
NoSuchElementError: An error occurred while running .setValue() command on <Element [name=@emailField]>: Timed out while waiting for element "input[name = "email"]" with "css selector" to be present for 5000 milliseconds.
at Page.fillUpData (/app/tests/page-objects/loginPage.js:13:21)
at Object.login (/app/tests/loginTest.js:9:8)
NoSuchElementError: An error occurred while running .setValue() command on <Element [name=@passField]>: Timed out while waiting for element "input[name = "password"]"
with "css selector" to be present for 5000 milliseconds.
at Page.fillUpData (/app/tests/page-objects/loginPage.js:13:21)
at Object.login (/app/tests/loginTest.js:10:8)
NoSuchElementError: An error occurred while running .click() command on <Element [name=@submitBt]>: Timed out while waiting for element "button[name = "submit"]" with
"css selector" to be present for 5000 milliseconds.
at Object.login (/app/tests/loginTest.js:11:8)
✖ Testing if the URL contains '/cards' in 5000ms - expected "contains '/cards'" but got: "http://frontend:8090/login" (5143ms)
at Object.login (/app/tests/loginTest.js:12:15)
FAILED: 1 assertions failed and 4 errors (28.22s)
When running tests locally, everything is working just fine. For local tests, I am using the chrome driver installed as dev dependency, accessing the frontend using http://localhost:8090/.
It is my first time dealing with E2E tests in docker, so I am not really sure what is going wrong. Any help is appreciated. Please find the source code below. Let me know if I need to add any more information.
- package.json
"scripts": {
...
"test": "nightwatch",
"test-selenium": "nightwatch -c nightwatch-selenium.conf.js",
...
},
- docker-compose.yml
services:
frontend:
build:
context: card-market-frontend/
dockerfile: Dockerfile
command: npm run serve
working_dir: /app
ports:
- "8090:8090"
chrome:
image: selenium/standalone-chrome:latest
hostname: chrome
privileged: true
shm_size: 2g
- When running the tests with the test-selenium command I am using the nightwatch.conf below:
const chromedriver = require("chromedriver");
require("dotenv").config();
module.exports = {
src_folders: ["/tests"],
page_objects_path: ["tests/page-objects"],
test_workers: false,
selenium: {
start_process: false,
cli_args: {
"webdriver.chrome.driver": chromedriver.path,
},
},
webdriver: {
start_process: false,
},
test_settings: {
default: {
selenium_port: 4444,
selenium_host: "chrome",
screenshots: {
enabled: true,
path: "tests_output/",
on_failure: true,
},
desiredCapabilities: {
browserName: "chrome",
chromeOptions: {
w3c: false,
args: ["--no-sandbox"],
},
},
},
},
};
- My page object loginPage.js
module.exports = {
url: `http://frontend:8090/login`,
elements: {
logoutBt: "#logoutBt",
loginBt: "#loginBt",
emailField: 'input[name = "email"]',
passField: 'input[name = "password"]',
submitBt: 'button[name = "submit"]',
},
commands: [
{
fillUpData(selector, data) {
return this.setValue(selector, data);
},
},
],
};
- The test that is running loginTest.js
module.exports = {
login(browser) {
const page = browser.page.loginPage();
const email = "[email protected]";
const pass = "coolPass";
page
.navigate()
.click("@loginBt")
.fillUpData("@emailField", email)
.fillUpData("@passField", pass)
.click("@submitBt")
.assert.urlContains("/cards");
},
};