0

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.

DixiPoowa
  • 133
  • 12
  • My initial guesses were either the `proxy` attribute of Protractor or start a node server to host the file beforehand, something like `http-server --port ` though in this last case, I'd need to have a "fake" path between `./` and `index.html` without having to create a folder (the path needs to verify a certain regex expression too for the initialisation to proceed) – DixiPoowa Jun 26 '19 at 09:33
  • Why do you need a fake path? Not sure I understand... – tehbeardedone Jun 27 '19 at 21:46
  • @tehbeardedone because the page seeks for specific parameters (not just query, the host and some elements of the path too) to properly initialise. When deployed, this page is included in a "local server" I guess and the URL then looks like "://://index.html?" – DixiPoowa Jul 01 '19 at 06:31

0 Answers0