I want to run UI tests on my pure vanilla ES5 JS (not Angular, and no modules, important for the rest I suppose) web page but, for that, I need to it on a specific URL (set a hostname and port, and other).
I use Jasmine and Karma for my unit test and run them automatically on Travis CI.
Now I reached the point where I want have functional/UI tests. For that, Protractor, in combination with Selenium, was recommended. But I'm encountering various problems (and I'm not even close to trying to incorporate it to Travis CI).
Short version
I have a local file index.html
and, in order for it to properly initialise, it requires a specific URL ("<protocole, mostly http>://<some-host>:<port>/<some-path>/index.html?<some-query>
").
I can currently access the index
, but only "locally" ("file:///<path-to-local-project>/index.html?<query>
") and therefore am only able to test the error use case where URL is malformed (hey, at least that's one of the tests).
I need a way to host/say "file:///<path-to-local-project>/index.html?<query>
" is accessed via "http://<some-host>:<port>/<some-path>/index.html?<query>
" because, when integrated to the full program, the page will be hosted somewhere and the URL contains valuable information for dynamic behaviors (really have no idea which keyword to use there ("host", "route"... ?) nor am I even certain this is to be configured in protractor or actually have to prepare some kind of hosting script just for testing. And keep in mind that, in the end, I want to be able to run these on Travis CI too)
What I have
In protractor.conf.js
exports.config = {
framework: 'jasmine',
baseUrl: 'file:///' + __dirname,
onPrepare: function(){
/**
* If you are testing against a non-angular site - set ignoreSynchronization setting to true
*
* If true, Protractor will not attempt to synchronize with the page before
* performing actions. This can be harmful because Protractor will not wait
* until $timeouts and $http calls have been processed, which can cause
* tests to become flaky. This should be used only when necessary, such as
* when a page continuously polls an API using $timeout.
*
* @type {boolean}
*/
browser.ignoreSynchronization = true;
global.dv = browser.driver;
// By default, Protractor use data:text/html,<html></html> as resetUrl, but
// location.replace from the data: to the file: protocol is not allowed
// (we'll get ‘not allowed local resource’ error), so we replace resetUrl with one
// with the file: protocol (this particular one will open system's root folder)
browser.resetUrl = 'file://';
},
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: [
'test/protractor/**/*.spec.js',
],
capabilities: {
browserName: 'chrome',
/*
proxy: {
proxyType: 'manual',
httpProxy: 'localhost:69/ID-420'
}, //*/
chromeOptions: {
// --allow-file-access-from-files - allow XHR from file://
args: ['allow-file-access-from-files']
}
}
};
In spec.js
describe('The main page', function () {
beforeEach(function () {
// jasmine.Ajax.install(); // how I intercept http requests in the unit tests. Here I may need another package apparently
console.log("browser", browser);
dv.ignoreSynchronization = true;
});
/*
afterEach(function () {
jasmine.Ajax.uninstall();
});
// */
it('should display an error message in the alert if no parameters are provided', function () {
browser.waitForAngularEnabled(false);
browser.get('/index.html');
element(by.className('ajs-content')).getText().then(console.log);
browser.sleep(5000);
expect(element(by.className('ajs-content')).getText()).toEqual("No ID or Host detected");
// expect(element(by.className('ajs-content')).getText()).toEqual(new EXCEPTIONS.NoHostOrIdInURI().description); // not working because unable to import scripts without **modules** (since ES5) but np, I can hard code the expected result
browser.getCurrentUrl().then(console.log);
});
});
Yes, this works, but if I can't set a custom URL for the file, I cannot test any other use case... And the topics I find online often are in Angular.
Previous question (way too vague) but maybe contain additional infos.