I am trying to run javascript mocha selenium-webdriver tests on my company's application using docker containers. I seem to have everything working except that I am unable to upload files. Prior to trying use my tests in a docker environment I was able to use it on our local servers and upload files with no issue using the a method like this:
const companyImage = process.cwd()+ '/img/backgroundmario.jpg';
const companyImageElem = await driver.findElement(By.xpath("//div/input[@type='file']"));
await companyImageElem.sendKeys(companyImage);
However, I have not been able to have any success when using docker containers. I mounted my img folder to my selenium/node-chrome-debug container which includes a VNC viewer and I can see that the images are present (and I can manually upload the images via the VNC viewer). However, despite numerous variations of providing paths to the images I cannot seem to get my images to upload. For some reason the working directory seems to be from my test container and not my node-chrome-debug container but even if I add the images to the test container and change the path to my test container directory with the images they do not upload either.
Here is a snippet of my code I am using for my test (it includes some stuff I wouldn't normally include, specifically the check for process.cwd()
and process.env.PWD
since I just wanted to see what the path was):
const {
Builder,
By,
Key,
until,
webdriver,
action
} = require('selenium-webdriver');
const mocha = require('mocha');
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
const {
makeUtilityBelt
} = require('./util')
chai.use(chaiAsPromised);
const fs = require('fs');
const expect = require('chai').expect;
const ciPassword = require('./envData').ciPassword;
const campManagerMail = '[email protected]';
const campManagerName = 'companycreator';
const campManagerUsername = 'companycreator';
const legacy = "http://node-web-client";
const companyImage = '/opt/test/images/backgroundmario.jpg';
var currentDir = process.cwd();
var appFolder = process.env.PWD;
const {
createLegacyAdmin,
createLegacyResellerCompany,
createLegacyBrandCompany,
createLegacyAgencyCompany,
createLegacyCampManager,
createLegacyClient,
createLegacyInfluencer
} = require('./legacyCreationQueries');
const {
getEmailId,
getUserEmailId,
getRandom,
verifyRandom,
accountSetup
} = require('./sqlutil');
describe('Creates a Company of Each Type via the Legacy Dashboard', function () {
this.timeout(1200000);
this.slow(20000);
let driver;
let util;
before(async function () {
driver = new Builder().forBrowser('chrome').usingServer('http://selenium_hub:4444/wd/hub').build();
util = makeUtilityBelt(driver);
await createLegacyCampManager(campManagerName, campManagerUsername, campManagerMail);
});
afterEach(function () {
let testCaseName = this.currentTest.title;
let testCaseStatus = this.currentTest.state;
if (testCaseStatus === 'failed') {
driver.takeScreenshot().then((data) => {
let screenshotPath = `./results/${testCaseName}.png`;
console.log(`Saving Screenshot as: ${screenshotPath}`);
fs.writeFileSync(screenshotPath, data, 'base64');
});
}
});
after(function () {
driver.quit();
});
describe('Load Legacy Corporate Site and Login to Legacy Dashboard', function () {
it('Loads into the Legacy Dashboard Successfully', async function () {
await driver.get(legacy);
await driver.wait(until.elementLocated(By.xpath("//p[contains(text(),'Sign In')]"), 10000));
await driver.sleep(3000);
const emailElem = await driver.findElement(By.xpath("//input[@id='email']"));
await util.sendKeys(emailElem, campManagerMail);
const pwElem = await driver.findElement(By.xpath("//input[@id='password']"));
await util.sendKeys(pwElem, ciPassword);
await driver.findElement(By.xpath("//button[contains(text(),'Sign In')]")).click();
await driver.wait(until.elementLocated(By.xpath("//div/ul[contains(@class, 'campaign-search-list')]"), 10000));
await driver.wait(until.elementLocated(By.xpath("//ul[@class='menu']/li/a/span[contains(text(),'User Management')]"), 10000));
await driver.sleep(5000);
await console.log("Below is the Current Working Directory");
await console.log(currentDir);
await driver.sleep(3000);
await console.log(appFolder);
await driver.sleep(3000);
await console.log("The above is the app folder");
await driver.sleep(2000);
const loginSuccessElem = await driver.findElement(By.xpath("//ul[@class='menu']/li/a/span[contains(text(),'User Management')]"));
let loginSuccess = await loginSuccessElem.isDisplayed();
await driver.sleep(3000);
await expect(loginSuccess, 'Legacy Login Failed').to.be.true;
});
});
describe('Creates a Reseller Company', function(){
const companyName = 'Reseller Test Company';
it('Navigates to Company Management and Begins Company Creation Process', async function(){
await driver.wait(until.elementLocated(By.xpath("//ul[@class='menu']/li/a/span[contains(text(),'Company Management')]"), 10000));
await driver.findElement(By.xpath("//ul[@class='menu']/li/a/span[contains(text(),'Company Management')]")).click();
await driver.sleep(8000);
await driver.wait(until.elementLocated(By.xpath("//h3[contains(text(),'Search Companies')]"), 10000));
await driver.wait(until.elementLocated(By.xpath("//a[contains(text(),'+ Create Company')]"), 10000));
await driver.sleep(8000);
await driver.findElement(By.xpath("//a[contains(text(),'+ Create Company')]")).click();
await driver.wait(until.elementLocated(By.xpath("//h3[contains(text(),'Create Company')]"), 10000));
const companyCreationPageElem = await driver.findElement(By.xpath("//h3[contains(text(),'Create Company')]"));
let companyCreationPage = await companyCreationPageElem.isDisplayed();
await expect(companyCreationPage, 'Company Creation Page failed to Load').to.be.true;
});
it('Fills in the required fields and creates New Reseller Company', async function(){
const companyDescription = 'This is a test description for a random test company blah blah blah';
const companyAddress = '777 Lucky Lane';
const companyCity = 'Las Vegas';
const companyState = 'Nevada';
const companyZip = '89104';
const companyNameElem = await driver.findElement(By.xpath("//input[@label='Company Name']"));
await util.sendKeys(companyNameElem, companyName);
await driver.sleep(1000);
const companyDescriptionElem = await driver.findElement(By.xpath("//textarea[@label='Company Description']"));
await util.sendKeys(companyDescriptionElem, companyDescription);
await driver.sleep(1000);
const companyTypeElem = await driver.findElement(By.xpath("//select"));
await companyTypeElem.click();
await driver.wait(until.elementLocated(By.xpath("//select/option"), 10000));
const companyTypeSelectElem = await driver.findElement(By.xpath("//select/option[@value='1']"));
await companyTypeSelectElem.click();
await driver.sleep(1000);
const addressElem = await driver.findElement(By.xpath("//input[@label='Address']"));
await util.sendKeys(addressElem, companyAddress);
await driver.sleep(1000);
const cityElem = await driver.findElement(By.xpath("//input[@label='City']"));
await util.sendKeys(cityElem, companyCity);
await driver.sleep(1000);
const stateElem = await driver.findElement(By.xpath("//input[@label='State']"));
await util.sendKeys(stateElem, companyState);
await driver.sleep(1000);
const zipElem = await driver.findElement(By.xpath("//input[@label='Zip Code']"));
await util.sendKeys(zipElem, companyZip);
await driver.sleep(1000);
await driver.findElement(By.xpath("//input[@type='file']")).sendKeys(companyImage);
await driver.sleep(1000);
await driver.wait(until.elementLocated(By.xpath("//img[@class='image-preview']"), 10000));
await driver.sleep(1000);
const submitButtonElem = await driver.findElement(By.xpath("//button[contains(text(),'Submit')]"));
await submitButtonElem.click();
await driver.wait(until.elementLocated(By.xpath("//h3[contains(text(),'Company Actions')]"), 10000));
await driver.wait(until.elementLocated(By.xpath("//p[@class='company-name']"), 10000));
const companySuccessElem = await driver.findElement(By.xpath("//p[@class='company-name'][contains(text(),'"+companyName+"')]"));
let companySuccess = await companySuccessElem.isDisplayed();
await expect(companySuccess, 'Failed to Create New Company').to.be.true;
});
});
});
This is the last thing stopping me from integrating my large number of test files with our CI/CD process but a huge number of my tests involve uploading files so it is a major issue.
Note: This is an edited copy of a question I asked on Stack Overflow. I am getting desperate because of my lack of progress.
Update:
The error I am receiving is: InvalidArgumentError: invalid argument: File not found : /opt/test/images/backgroundmario.jpg (Session info: chrome=77.0.3865.75)
. This is puzzling to me in several ways based on what I have read and what people in the official Selenium Slack channel had told me.
First of all, in my docker_test_1
container (which contains the test file) the path opt/test/images/<filename>
actually does point to the file. However, I was told in the Selenium Slack that I needed to have my images in the node-chrome-debug
container with the path opt/images
So I mounted the images folder to the selenium-chrome-debug
container in opt/images
but if I use that path in my test file it does not attach the image either and I receive a similar error. However, if I use VNC viewer I can see that in opt/images
the images are there and I can manually upload them through the VNC browser. So despite trying numerous paths I can not seem to get my images to upload despite the fact that when running my tests on a local environment without docker the images upload without issue.
Another thing that puzzled me is that the result of
var currentDir = process.cwd();
var appFolder = process.env.PWD;
is opt/test
when I would have assumed that it would have been the working directory for the selenium-node-chrome
container based on what I was told in the Selenium Slack channel.
I tried changing the path for my images to opt/test/images/
but they still do not upload.
I am not someone who tries ask questions for something that is a simple google search away but I have been struggling for several days with this issue and I can't seem to find any solution or helpful advice.