Using Protractor in Electron

Deadly 提交于 2019-12-03 15:14:36

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.

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.

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.

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.

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