text: const assert  = require('assert');
  const brains  = require('./helpers/brains');
  const Browser = require('../src');
  
  
  describe('Window', function() {
    const browser = new Browser();
  
    before(function() {
      return brains.ready();
    });
  
    // -- Alert, confirm and popup; form when we let browsers handle our UI --
  
    describe('.alert', function() {
      let alert = null;
  
      before(async function() {
        brains.static('/window/alert', `
          <html>
            <script>
              alert("Hi");
              alert("Me again");
            </script>
          </html>
        `);
        browser.on('alert', function(message) {
          alert = message;
        });
        await browser.visit('/window/alert');
      });
  
      it('should emit alert event with message', function() {
        assert.equal(alert, 'Me again');
      });
    });
  
    describe('.confirm', function() {
      const questions = [];
  
      before(async function() {
        brains.static('/window/confirm', `
          <html>
            <script>
              window.first = confirm("continue?");
              window.second = confirm("more?");
              window.third = confirm("silent?");
            </script>
          </html>
        `);
  
        browser.on('confirm', function(confirm) {
          questions.push(confirm.question);
        });
        browser.on('confirm', function(confirm) {
          if (confirm.question === 'continue?')
            confirm.response = true;
        });
        browser.on('confirm', function(confirm) {
          if (confirm.question === 'more?')
            confirm.response = '';
        });
  
        await browser.visit('/window/confirm');
      });
  
      it('should emit confirm event with message', function() {
        assert.deepEqual(questions, ['continue?', 'more?', 'silent?']);
      });
      it('should return last response from event handler', function() {
        assert.equal(browser.window.first, true);
      });
      it('should convert response to boolean', function() {
        assert.equal(browser.window.second, false);
      });
      it('should default to return true', function() {
        assert.equal(browser.window.third, true);
      });
    });
  
  
    describe('.prompt', function() {
      const questions = [];
  
      before(async function() {
        brains.static('/window/prompt', `
          <html>
            <script>
              window.first = prompt("age");
              window.second = prompt("gender", "missing");
              window.third = prompt("location", "here");
              window.fourth = prompt("weight", 180);
            </script>
          </html>
        `);
  
        browser.on('prompt', function(prompt) {
          questions.push(prompt.question);
        });
        browser.on('prompt', function(prompt) {
          if (prompt.question === 'age')
            prompt.response = 31;
        });
        browser.on('prompt', function(prompt) {
          if (prompt.question === 'gender')
            prompt.response = 'unknown';
        });
        browser.on('prompt', function(prompt) {
          if (prompt.question === 'weight')
            prompt.response = false;
        });
  
        await browser.visit('/window/prompt');
      });
  
      it('should emit confirm event with message', function() {
        assert.deepEqual(questions, ['age', 'gender', 'location', 'weight']);
      });
      it('should return event handler response as string', function() {
        assert.equal(browser.window.first, '31');
      });
      it('should return last response from event handler', function() {
        assert.equal(browser.window.second, 'unknown');
      });
      it('should return default value if no response specified', function() {
        assert.equal(browser.window.third, 'here');
      });
      it('should return null if response if response is falsy', function() {
        assert.equal(browser.window.fourth, '');
      });
    });
  
  
    // -- This part deals with various windows properties ---
  
    describe('.screen', function() {
      it('should have a screen object available', function() {
        browser.assert.evaluate('screen.width',       1280);
        browser.assert.evaluate('screen.height',      800);
        browser.assert.evaluate('screen.left',        0);
        browser.assert.evaluate('screen.top',         0);
        browser.assert.evaluate('screen.availLeft',   0);
        browser.assert.evaluate('screen.availTop',    0);
        browser.assert.evaluate('screen.availWidth',  1280);
        browser.assert.evaluate('screen.availHeight', 800);
        browser.assert.evaluate('screen.colorDepth',  24);
        browser.assert.evaluate('screen.pixelDepth',  24);
      });
    });
  
  
    describe('.navigator', function() {
      before(async function() {
        brains.static('/window/navigator', `
          <html>
            <head>
              <title>Whatever</title>
            </head>
            <body>Hello World</body>
          </html>
        `);
        await browser.visit('/window/navigator');
      });
  
      it('should exist', function() {
        browser.assert.evaluate('navigator');
      });
      it('javaEnabled should be false', function() {
        browser.assert.evaluate('navigator.javaEnabled()', false);
      });
      it('language should be set to en-US', function() {
        browser.assert.evaluate('navigator.language', 'en-US');
      });
      it('plugins should be empty array', function() {
        browser.assert.evaluate('navigator.plugins.length', 0);
      });
      it('plugins should have no items', function() {
        browser.assert.evaluate('navigator.plugins.item(0)', undefined);
        browser.assert.evaluate('navigator.plugins.namedItem("Flash")', undefined);
      });
      it('mimeTypes should be empty array', function() {
        browser.assert.evaluate('navigator.mimeTypes.length', 0);
      });
      it('mimeTypes should have no items', function() {
        browser.assert.evaluate('navigator.mimeTypes.item(0)', undefined);
        browser.assert.evaluate('navigator.mimeTypes.namedItem("Flash")', undefined);
      });
    });
  
  
    describe('.fetch', function() {
      before(function() {
        brains.get('/window/fetch/data', (req, res) => {
          assert.equal(req.get('X-Test'), 'ok');
          res.send();
        });
      });
  
      it('should process HeadersInit as an array from different context', async function() {
        brains.static('/window/fetch/array-test', `
          <html>
            <script>
              fetch('data', {
                headers: [
                  ['X-Test', 'ok']
                ]
              }).then(function() {
                document.dispatchEvent(new Event('fetched'));
              });
            </script>
          </html>
        `);
  
        await browser.visit('/window/fetch/array-test');
        await new Promise(resolve => {
          browser.document.addEventListener('fetched', resolve);
        });
      });
  
      it('should process HeadersInit as an object from different context', async function() {
        brains.static('/window/fetch/object-test', `
          <html>
            <script>
              fetch('data', {
                headers: {
                  'X-Test': 'ok'
                }
              }).then(function() {
                document.dispatchEvent(new Event('fetched'));
              });
            </script>
          </html>
        `);
  
        await browser.visit('/window/fetch/object-test');
        await new Promise(resolve => {
          browser.document.addEventListener('fetched', resolve);
        });
      });
    });
  
    describe('atob', function() {
      it('should decode base-64 string', function() {
        browser.open();
        browser.assert.evaluate('atob("SGVsbG8sIHdvcmxk")', 'Hello, world');
      });
    });
  
    describe('btoa', function() {
      it('should encode base-64 string', function() {
        browser.open();
        browser.assert.evaluate('btoa("Hello, world")', 'SGVsbG8sIHdvcmxk');
      });
    });
  
    describe('DataView', function () {
      it('should create a DataView', function () {
        const window = browser.open();
        assert.equal(window.DataView, DataView);
        browser.assert.evaluate('new DataView(new ArrayBuffer(8)).byteLength', '8');
      });
    });
  
    describe('onload', function() {
      before(async function() {
        brains.static('/windows/onload', `
          <html>
            <head>
              <title>The Title!</title>
              <script type="text/javascript" language="javascript" charset="utf-8">
                var about = function (e) {
                  var info = document.getElementById('das_link');
                  info.innerHTML = (parseInt(info.innerHTML) + 1) + ' clicks here';
                  e.preventDefault();
                  return false;
                }
                window.onload = function () {
                  var info = document.getElementById('das_link');
                  info.addEventListener('click', about, false);
                }
              </script>
            </head>
            <body>
              <a id="das_link" href="/no_js.html">0 clicks here</a>
            </body>
          </html>
        `);
  
        await browser.visit('/windows/onload');
        await browser.clickLink('#das_link');
      });
  
      it('should fire when document is done loading', function() {
        browser.assert.text('body', '1 clicks here');
      });
    });
  
  
    describe('refresh', function() {
      before(function() {
        brains.static('/windows/refreshed', `
          <html>
            <head>
              <title>Done</title>
            <body>Redirection complete.</body>
          </html>
        `);
        brains.get('/windows/refresh', function(req, res) {
          // Don't refresh page more than once
          const referrer  = req.headers.referer;
          const refreshed = referrer && referrer.endsWith('/windows/refresh');
          if (refreshed)
            res.send(`
              <html>
                <head><title>Done</title></head>
                <body></body>
              </html>
            `);
          else {
            const value = req.query.url ? `1; url=${req.query.url}` : '1'; // Refresh to URL or reload self
            res.send(`
              <html>
                <head>
                  <title>Refresh</title>
                  <meta http-equiv="refresh" content="${value}">
                </head>
                <body>
                  You are being redirected.
                </body>
              </html>
            `);
          }
        });
      });
  
      it('should follow a meta refresh to a relative URL', async function() {
        await browser.visit('/windows/refresh?url=/windows/refreshed');
        browser.assert.url('/windows/refreshed');
      });
  
      it('should follow a meta refresh to an absolute URL', async function() {
        await browser.visit('/windows/refresh?url=http://example.com/');
        browser.assert.url('http://example.com/');
      });
  
      it('should refresh the current page if no URL is given', async function() {
        await browser.visit('/windows/refresh');
        browser.assert.url('http://example.com/windows/refresh');
        browser.assert.text('title', 'Done');
      });
  
      it('should indicated that the last request was redirected', async function() {
        await browser.visit('/windows/refresh?url=/windows/refreshed');
        browser.assert.redirected();
      });
  
      describe('meta refresh page', function() {
  
        before(async function() {
          browser.visit('/windows/refresh');
  
          function complete() {
            return !!browser.query('meta');
          }
  
          await browser.wait({ function: complete });
        });
  
        it('should check completion function on original page', function() {
          browser.assert.url('http://example.com/windows/refresh');
          // Check the refresh page.
          browser.assert.text('title', 'Refresh');
        });
  
        describe('continue', function() {
          before(function() {
            return browser.wait();
          });
  
          it('should continue to next page', function() {
            browser.assert.url('http://example.com/windows/refresh');
            browser.assert.text('title', 'Done');
          });
        });
  
      });
  
  
      afterEach(function() {
        browser.deleteCookies();
      });
  
    });
  
  
    describe('refresh with timeout', function() {
      before(function() {
        brains.static('/windows/foo', `
          <html>
            <title>Foo</title>
          </html>
        `);
        brains.static('/windows/bar', `
          <html>
            <title>Bar</title>
          </html>
        `);
        brains.get('/windows/refresh-with-timeout', function(req, res) {
          res.send(`
            <html>
              <head>
                <title>Refresh</title>
                <meta http-equiv="refresh" content="1; url=/windows/foo">
              </head>
              <body>
                <script>
                  setTimeout(function() {
                    window.location = '/windows/bar';
                  }, 10);
                </script>
              </body>
            </html>
          `);
        });
      });
  
  
      it('should honor the timeout', async function() {
        await browser.visit('/windows/refresh-with-timeout');
        browser.assert.url('/windows/bar');
      });
  
  
      afterEach(function() {
        browser.deleteCookies();
      });
  
    });
  
  
    describe('resize', function() {
      it('should change window dimensions', function() {
        const window = browser.open();
        assert.equal(window.innerWidth, 1024);
        assert.equal(window.innerHeight, 768);
        window.resizeBy(-224, -168);
        assert.equal(window.innerWidth, 800);
        assert.equal(window.innerHeight, 600);
      });
    });
  
  
    after(function() {
      browser.destroy();
    });
  });
  