import * as http from 'http';
import * as net from 'net';
import express from 'express';
import puppeteer from 'puppeteer';
import { expect } from 'chai';
import {
  EventName,
  addEventListenersToPuppeteerPage,
  launchBrowser,
} from './util';

describe('utility functions for Puppeteer tests', async () => {
  let browser: puppeteer.Browser;
  before(async () => {
    browser = await launchBrowser();
  });
  after(async () => {
    await browser.close();
  });

  let page: puppeteer.Page;
  beforeEach(async () => {
    page = await browser.newPage();
  });
  afterEach(async () => {
    await page.close();
  });

  describe('addEventListenersToPuppeteerPage', () => {
    let server: http.Server;
    let testPageUrl: string;

    // Type for the custom event details used in this test.
    interface TestEventDetail {
      msg: string;
    }

    beforeEach(async () => {
      // Start an HTTP server on a random, unused port.
      const app = express();
      await new Promise((resolve) => {
        server = app.listen(0, () => resolve(undefined));
      });
      testPageUrl = `http://localhost:${
        (server!.address() as net.AddressInfo).port
      }/`;

      // Serve a test page that triggers various custom events.
      app.get('/', (req, res) => res.send(`
        <html>
          <head>
            <script>
              async function triggerEvent(name, detail) {
                document.dispatchEvent(
                    new CustomEvent(name, {detail: detail, bubbles: true}));
                await new Promise((resolve) => setTimeout(resolve, 10));
              }

              // This is necessary as await is not allowed outside a function.
              async function main() {
                await triggerEvent('alpha-event',
                                   {msg: 'Only occurrence of alpha-event'});

                await triggerEvent('beta-event',
                                   {msg: '1st occurrence of beta-event'});
                await triggerEvent('beta-event',
                                   {msg: '2nd occurrence of beta-event'});
                await triggerEvent('beta-event',
                                   {msg: '3rd occurrence of beta-event'});

                // No test case should create a promise for this event. The goal
                // is to test that no promise accidentally resolves to this guy.
                await triggerEvent('ignored-event',
                                   {msg: 'No test case should catch me'});

                await triggerEvent('gamma-event',
                                   {msg: '1st occurrence of gamma-event'});
                await triggerEvent('gamma-event',
                                   {msg: '2nd occurrence of gamma-event'});
                await triggerEvent('gamma-event',
                                   {msg: '3rd occurrence of gamma-event'});
              }
              main();
            </script>
          </head>
          <body>
            <h1>Hello, world!</h1>
            <p>I am just a test page.</p>
          </body>
        </html>
      `));
    });

    afterEach((done) => server.close(done));

    it('renders test page correctly', async () => {
      await page.goto(testPageUrl);
      expect(
        await page.$eval('h1', (el) => (el as HTMLElement).innerText),
      ).to.equal('Hello, world!');
      expect(
        await page.$eval('p', (el) => (el as HTMLElement).innerText),
      ).to.equal('I am just a test page.');
    });

    it('catches events in the right order', async () => {
      // Add event listeners.
      const eventNames: EventName[] = [
        'alpha-event',
        'beta-event',
        'gamma-event',
        // We purposefully add a listener for ignored-event, but we won't try
        // to catch any such events. This is to test that uncaught events do
        // not interfere with the events we're trying to catch.
        'ignored-event',
      ];
      const eventPromise = await addEventListenersToPuppeteerPage(
        page,
        eventNames,
      );

      // We will collect the Event object details in the order they are caught.
      const eventDetailsInOrder: TestEventDetail[] = [];
      const trackCaughtOrder = async (
        anEventPromise: Promise<TestEventDetail>,
      ) => {
        const detail = await anEventPromise;
        eventDetailsInOrder.push(detail);
        return detail;
      };

      // We create event promises in an arbitrary order to test that this has no
      // effect in the order that events are caught.
      const allEventDetailsPromise = Promise.all([
        trackCaughtOrder(eventPromise<TestEventDetail>('gamma-event')),
        trackCaughtOrder(eventPromise<TestEventDetail>('alpha-event')),
        trackCaughtOrder(eventPromise<TestEventDetail>('gamma-event')),
        trackCaughtOrder(eventPromise<TestEventDetail>('beta-event')),
        trackCaughtOrder(eventPromise<TestEventDetail>('gamma-event')),
        trackCaughtOrder(eventPromise<TestEventDetail>('beta-event')),
        trackCaughtOrder(eventPromise<TestEventDetail>('beta-event')),
      ]);

      await page.goto(testPageUrl);

      // Assert that each promise returned the expected event detail.
      const allEventDetails = await allEventDetailsPromise;
      expect(allEventDetails).to.have.length(7);
      expect(allEventDetails[0].msg).to.equal('1st occurrence of gamma-event');
      expect(allEventDetails[1].msg).to.equal('Only occurrence of alpha-event');
      expect(allEventDetails[2].msg).to.equal('2nd occurrence of gamma-event');
      expect(allEventDetails[3].msg).to.equal('1st occurrence of beta-event');
      expect(allEventDetails[4].msg).to.equal('3rd occurrence of gamma-event');
      expect(allEventDetails[5].msg).to.equal('2nd occurrence of beta-event');
      expect(allEventDetails[6].msg).to.equal('3rd occurrence of beta-event');

      // Assert that promises were resolved in the expected order.
      expect(eventDetailsInOrder).to.have.length(7);
      expect(eventDetailsInOrder[0].msg).to.equal(
        'Only occurrence of alpha-event',
      );
      expect(eventDetailsInOrder[1].msg).to.equal(
        '1st occurrence of beta-event',
      );
      expect(eventDetailsInOrder[2].msg).to.equal(
        '2nd occurrence of beta-event',
      );
      expect(eventDetailsInOrder[3].msg).to.equal(
        '3rd occurrence of beta-event',
      );
      expect(eventDetailsInOrder[4].msg).to.equal(
        '1st occurrence of gamma-event',
      );
      expect(eventDetailsInOrder[5].msg).to.equal(
        '2nd occurrence of gamma-event',
      );
      expect(eventDetailsInOrder[6].msg).to.equal(
        '3rd occurrence of gamma-event',
      );
    });

    it('fails if event promise function is called with unknown event', async () => {
      const eventPromise = await addEventListenersToPuppeteerPage(page, [
        'foo-event',
      ]);
      expect(() => eventPromise('invalid-event')).to.throw(
        'no event listener for "invalid-event"',
      );
    });
  });
});
