Using Protractor in Electron

岁酱吖の 提交于 2019-12-09 13:36:39

问题


I am trying to set up unit tests and e2e tests for an application I have running with Electron using Protractor. I've been refering to many different posts (this one did help), but I still get an error I don't understand :

Message:
  Error while waiting for Protractor to sync with the page: "angular could not be found on the window"
Stacktrace:
  undefined

My conf.js file looks like this:

exports.config = {
    directConnect : true,
    seleniumAddress: 'http://localhost:4444/wd/hub',
    baseUrl:"file://home/me/workspace/testing-project/main.js",
    capabilities: {
        browserName: "chrome",
        chromeOptions: {
            binary: "/home/me/.linuxbrew/lib/node_modules/electron-prebuilt/dist/electron",
            args: ["--test-type=webdriver"]
        }
    },
    specs: ['todo-specs.js'],
    onPrepare: function(){
        browser.resetUrl = "file://";
        browser.driver.get("file://");
    }
};

Considering the documentation given on the Protractor website, I am under the impression that I don't need to install anything else (Jasmine for example).
What surprises me is that even though the path to the main.js (that starts the application accordingly to Electron's specifications) is correct, I can't see anything in the Electron window that pops up.
Did any of you encountered this issue? Did you manage to resolve it?


回答1:


Apparently, using the electron binary is not enough to actually launch your application. However, by building the binary for your application and linking it into your conf.js file works.
I have been able to reduce my file to this:
conf.js

exports.config = {
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['test-spec.js'],
    capabilities: {
        browserName: "chrome",
        chromeOptions: {
            binary: "./dist/myAwesomeApp/myAwesomeAppBinary"
        }
    },
    onPrepare: function () {
        browser.resetUrl = "file://";
    }
};

By doing it this way, there is no need to describe a baseUrl or to use browser.get() nor browser.driver.get() to start the app in Electron.
However, I would have preferred not to have to build the app binary, but I don't think it is possible for now.




回答2:


Protractor does not work well with Electron, as it does not have access to the Electron-specific APIs and the renderer cannot be properly controlled. Spectron, on the other hand, is designed specifically for Electron and has an API very similar to Protractor. It gives you access to test both the main and renderer processes at the same time.

I had to copy some code from Protractor to get it to wait for Angular 2 to load properly. (Disregard if you aren't using Angular.) Here is a working example:

const path = require('path');
const electron = require('electron-prebuilt');
var Application = require('spectron').Application
var assert = require('assert')

let appPath = path.join(__dirname, '..', 'dist');

function awaitAngular2(client) {
  client.timeoutsAsyncScript(5000);
  // From: https://github.com/angular/protractor/blob/master/lib/clientsidescripts.js
  // Returns a promise that resolves when all of Angular 2's components are loaded and stable
  return client.executeAsync(function(done) {
    try {
      var testabilities = window.getAllAngularTestabilities();
      var count = testabilities.length;
      var decrement = function() {
        count--;
        if (count === 0) {
          done();
        }
      };
      testabilities.forEach(function(testability) {
        testability.whenStable(decrement);
      });
    } catch (err) {
      done(err.message);
    }
  });
}

describe('application launch', function () {
  this.timeout(10000)

  beforeEach(function () {
    this.app = new Application({
      path: electron,
      args: [appPath]
    });
    return this.app.start().then(() => {
      return awaitAngular2(this.app.client);
    })
  });

  afterEach(function () {
    if (this.app && this.app.isRunning()) {
      return this.app.stop()
    }
  });

  it('shows an initial window', function () {
    return this.app.client.getWindowCount().then(function (count) {
      assert.equal(count, 1)
    })
  });

  it('shows a headline', function () {
    this.app.client.getText('app-banner h1').then(function (bannerText) {
      assert.equal(bannerText, 'Tour of Heroes');
    })
  });
});

If you have multiple .spec files that you want to run automatically, then you can integrate this with Jasmine or Mocha Node.js test runners.




回答3:


Protractor is designed to work with angular apps, but you can also use it for "non-angular" apps.

If you are using angular with your electron app, then it will just look at the ng-app and sync.

If you are not using an angular app, you should set isAngularSite(false), then it will not try to synchronize.




回答4:


Assuming that you launch protractor from the root of your project where main.js is located, you should be able to set your protractor.conf.js like so:

exports.config = {
    directConnect: true,
    capabilities: {
        browserName: 'chrome',
        chromeOptions: {
            binary: 'node_modules/.bin/electron',
            args: ['app=main.js']
        }
    },
    onPrepare: function () {
        browser.resetUrl = "file://"
    }
}

The options for capabilities.chromeOptions.args are what is passed electron. For more documentation on capabilities, selenium has documentation on it here.



来源:https://stackoverflow.com/questions/33440031/using-protractor-in-electron

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!