const assert = require('assert');
const liveServer = require('live-server');
const {
  before,
  after,
  beforeEach,
  afterEach,
  describe,
  it
} = require('mocha');
const testContainer = process.env.MOCHA_CONTAINER;
const setup = require(`./${testContainer}-test-setup`);

let app;

const params = {
  port: 5000,
  host: '127.0.0.1',
  root: 'src',
  open: false,
  ignore: '*'
};

describe('Window API', function(done) {
  const timeout = 60000;
  this.timeout(timeout);

  before(() => {
    liveServer.start(params);
  });

  after(() => {
    liveServer.shutdown();
  });

  beforeEach(() => {
    app = setup(timeout);

    return app.start();
  });

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

  const executeAsyncJavascript = (client, script) => {
    return client.executeAsync(script);
  };

  const openNewWindow = (options) => {
    const script = `
      ssf.app.ready().then(() => {
        var callback = arguments[arguments.length - 1];
        new ssf.Window(${JSON.stringify(options)});
        setTimeout(() => callback(), 500);
      });
    `;
    return executeAsyncJavascript(app.client, script);
  };

  const callWindowMethod = (method) => {
    const script = `
      var callback = arguments[arguments.length - 1];
      var currentWin = ssf.Window.getCurrentWindow();
      currentWin.${method}().then((data) => {
        callback(data);
      });
    `;

    return executeAsyncJavascript(app.client, script);
  };

  it('Check ssf.Window is available globally', function() {
    const script = `
      var callback = arguments[arguments.length - 1];
      if (ssf.Window !== undefined) {
        callback();
      }
    `;
    return executeAsyncJavascript(app.client, script);
  });

  it('Check window constructor opens a new window', function() {
    return openNewWindow({url: 'about:blank', name: 'test', show: true, child: true}).then((result) => {
      return app.client.getWindowCount().then((count) => {
        assert.equal(count, 2);
      });
    });
  });

  it('Check new window has correct x position', function() {
    const windowTitle = 'windownamex';
    const xValue = 100;
    const windowOptions = {
      url: 'http://localhost:5000/index.html',
      name: windowTitle,
      show: true,
      x: xValue,
      y: 0,
      child: true
    };

    return app.client.isVisible('.visible-check')
      .then(() => openNewWindow(windowOptions))
      .then(() => app.client.windowHandles())
      .then((handles) => app.client.window(handles.value[1]))
      .then(() => app.client.waitForVisible('.visible-check'))
      .then(() => callWindowMethod('getBounds'))
      .then((result) => assert.equal(result.value.x, xValue));
  });

  it('Check new window has correct y position', function() {
    const windowTitle = 'windownamey';
    const yValue = 100;
    const windowOptions = {
      url: 'http://localhost:5000/index.html',
      name: windowTitle,
      show: true,
      x: 0,
      y: yValue,
      child: true
    };

    return app.client.isVisible('.visible-check')
      .then(() => openNewWindow(windowOptions))
      .then(() => app.client.windowHandles())
      .then((handles) => app.client.window(handles.value[1]))
      .then(() => app.client.waitForVisible('.visible-check'))
      .then(() => callWindowMethod('getBounds'))
      .then((result) => assert.equal(result.value.y, yValue));
  });
});

@@ -800,23 +800,89 @@
 , script
+, ...args
 ) =%3E %7B%0A
+    // script is passed a callback as its final argument%0A
     retu
@@ -906,24 +906,33 @@
 Async(script
+, ...args
 );%0A  %7D;%0A%0A  c
@@ -975,155 +975,147 @@
     
-const script = %60%0A      ssf.app.ready().then(() =%3E %7B%0A        var callback = arguments%5Barguments.length - 1%5D;%0A        new ssf.Window($%7BJSON.stringify
+/* eslint-disable no-undef, no-new */%0A    const script = (options, callback) =%3E %7B%0A      ssf.app.ready().then(() =%3E %7B%0A        new ssf.Window
 (opt
@@ -1119,18 +1119,16 @@
 options)
-%7D)
 ;%0A      
@@ -1174,27 +1174,68 @@
     %7D);%0A    
-%60
+%7D
 ;%0A
+    /* eslint-enable no-undef, no-new */%0A
     return e
@@ -1266,32 +1266,41 @@
 p.client, script
+, options
 );%0A  %7D;%0A%0A  const
@@ -1329,24 +1329,58 @@
 ethod) =%3E %7B%0A
+    /* eslint-disable no-undef */%0A
     const sc
@@ -1382,35 +1382,32 @@
 st script = 
-%60%0A      var
+(method,
  callback = 
@@ -1407,43 +1407,14 @@
 back
+)
  =
- arguments%5Barguments.length - 1%5D;
+%3E %7B
 %0A   
@@ -1484,18 +1484,16 @@
 tWin
-.$%7B
+%5B
 method
-%7D
+%5D
 ().t
@@ -1546,19 +1546,51 @@
 %7D);%0A    
-%60
+%7D
 ;%0A
+    /* eslint-enable no-undef */
 %0A    ret
@@ -1630,24 +1630,32 @@
 ient, script
+, method
 );%0A  %7D;%0A%0A  i
@@ -1703,32 +1703,66 @@
 ', function() %7B%0A
+    /* eslint-disable no-undef */%0A
     const script
@@ -1768,28 +1768,17 @@
 t = 
-%60%0A      var 
+(
 callback
  = a
@@ -1777,43 +1777,14 @@
 back
+)
  =
- arguments%5Barguments.length - 1%5D;
+%3E %7B
 %0A   
@@ -1854,10 +1854,43 @@
     
-%60;
+%7D;%0A    /* eslint-enable no-undef */
 %0A   

Change function strings to functions in tests (#76)