import { module, test } from 'qunit';
import { focus, setupContext, teardownContext, registerHook } from '@ember/test-helpers';
import { buildInstrumentedElement, insertElement } from '../../helpers/events';
import { isIE11 } from '../../helpers/browser-detect';
import hasEmberVersion from '@ember/test-helpers/has-ember-version';

let focusSteps = ['focus', 'focusin'];

if (isIE11) {
  focusSteps = ['focusin', 'focus'];
}

module('DOM Helper: focus', function (hooks) {
  if (!hasEmberVersion(2, 4)) {
    return;
  }

  let context, element;

  hooks.beforeEach(function () {
    context = {};
  });

  hooks.afterEach(async function () {
    element.setAttribute('data-skip-steps', true);

    if (element) {
      element.parentNode.removeChild(element);
      element = null;
    }
    // only teardown if setupContext was called
    if (context.owner) {
      await teardownContext(context);
    }
    document.getElementById('ember-testing').innerHTML = '';
  });

  test('it executes registered focus hooks', async function (assert) {
    assert.expect(3);

    element = document.createElement('input');
    insertElement(element);

    let startHook = registerHook('focus', 'start', () => {
      assert.step('focus:start');
    });
    let endHook = registerHook('focus', 'end', () => {
      assert.step('focus:end');
    });

    await focus(element);

    assert.verifySteps(['focus:start', 'focus:end']);

    startHook.unregister();
    endHook.unregister();
  });

  test('focusing a div via selector with context set', async function (assert) {
    element = buildInstrumentedElement('div');

    await setupContext(context);
    assert.rejects(focus(`#${element.id}`), /is not focusable/);
  });

  test('focusing a div via element with context set', async function (assert) {
    element = buildInstrumentedElement('div');

    await setupContext(context);
    assert.rejects(focus(element), /is not focusable/);
  });

  test('focusing a disabled form control', async function (assert) {
    element = buildInstrumentedElement('input');
    element.setAttribute('disabled', '');

    await setupContext(context);
    assert.rejects(
      focus(`#${element.id}`, 'foo'),
      'Error: [object HTMLInputElement] is not focusable'
    );
  });

  test('does not run sync', async function (assert) {
    element = buildInstrumentedElement('input');

    let promise = focus(element);

    assert.verifySteps([]);

    await promise;

    assert.verifySteps(focusSteps);
  });

  test('rejects if selector is not found', async function (assert) {
    element = buildInstrumentedElement('div');

    await setupContext(context);

    assert.rejects(
      focus(`#foo-bar-baz-not-here-ever-bye-bye`),
      /Element not found when calling `focus\('#foo-bar-baz-not-here-ever-bye-bye'\)`/
    );
  });

  test('focusing a input via selector with context set', async function (assert) {
    element = buildInstrumentedElement('input');

    await setupContext(context);
    await focus(`#${element.id}`);

    assert.verifySteps(focusSteps);
    assert.strictEqual(document.activeElement, element, 'activeElement updated');
  });

  test('focusing a input via element with context set', async function (assert) {
    element = buildInstrumentedElement('input');

    await setupContext(context);
    await focus(element);

    assert.verifySteps(focusSteps);
    assert.strictEqual(document.activeElement, element, 'activeElement updated');
  });

  test('focusing a input via element without context set', async function (assert) {
    element = buildInstrumentedElement('input');

    await focus(element);

    assert.verifySteps(focusSteps);
    assert.strictEqual(document.activeElement, element, 'activeElement updated');
  });

  test('focusing a input via selector without context set', async function (assert) {
    element = buildInstrumentedElement('input');

    assert.rejects(
      focus(`#${element.id}`),
      /Must setup rendering context before attempting to interact with elements/
    );
  });
});

@@ -1133,24 +1133,28 @@
 t(element);%0A
+    
 %0A    let sta
@@ -1335,24 +1335,36 @@
 );%0A    %7D);%0A%0A
+    try %7B%0A  
     await fo
@@ -1370,32 +1370,34 @@
 ocus(element);%0A%0A
+  
     assert.verif
@@ -1434,21 +1434,38 @@
 end'%5D);%0A
-%0A
+    %7D finally %7B%0A 
     
+ 
 startHoo
@@ -1484,16 +1484,18 @@
 ();%0A    
+  
 endHook.
@@ -1508,16 +1508,22 @@
 ster();%0A
+    %7D%0A
   %7D);%0A%0A 

Update tests/unit/dom/focus-test.js