/**
 * Copyright Microsoft Corporation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { it, expect } from './fixtures';
it('should dispatch click event', async ({page, server}) => {
  await page.goto(server.PREFIX + '/input/button.html');
  await page.dispatchEvent('button', 'click');
  expect(await page.evaluate(() => window['result'])).toBe('Clicked');
});
it('should dispatch click event properties', async ({page, server}) => {
  await page.goto(server.PREFIX + '/input/button.html');
  await page.dispatchEvent('button', 'click');
  expect(await page.evaluate('bubbles')).toBeTruthy();
  expect(await page.evaluate('cancelable')).toBeTruthy();
  expect(await page.evaluate('composed')).toBeTruthy();
});
it('should dispatch click svg', async ({page}) => {
  await page.setContent(`
    
  `);
  await page.dispatchEvent('circle', 'click');
  expect(await page.evaluate(() => window['__CLICKED'])).toBe(42);
});
it('should dispatch click on a span with an inline element inside', async ({page, server}) => {
  await page.setContent(`
    
    
  `);
  await page.dispatchEvent('span', 'click');
  expect(await page.evaluate(() => window['CLICKED'])).toBe(42);
});
it('should dispatch click after navigation ', async ({page, server}) => {
  await page.goto(server.PREFIX + '/input/button.html');
  await page.dispatchEvent('button', 'click');
  await page.goto(server.PREFIX + '/input/button.html');
  await page.dispatchEvent('button', 'click');
  expect(await page.evaluate(() => window['result'])).toBe('Clicked');
});
it('should dispatch click after a cross origin navigation ', async ({page, server}) => {
  await page.goto(server.PREFIX + '/input/button.html');
  await page.dispatchEvent('button', 'click');
  await page.goto(server.CROSS_PROCESS_PREFIX + '/input/button.html');
  await page.dispatchEvent('button', 'click');
  expect(await page.evaluate(() => window['result'])).toBe('Clicked');
});
it('should not fail when element is blocked on hover', async ({page, server}) => {
  await page.setContent(`
  
    
    
  `);
  await page.dispatchEvent('button', 'click');
  expect(await page.evaluate(() => window['clicked'])).toBeTruthy();
});
it('should dispatch click when node is added in shadow dom', async ({page, server}) => {
  await page.goto(server.EMPTY_PAGE);
  const watchdog = page.dispatchEvent('span', 'click');
  await page.evaluate(() => {
    const div = document.createElement('div');
    div.attachShadow({mode: 'open'});
    document.body.appendChild(div);
  });
  await page.evaluate(() => new Promise(f => setTimeout(f, 100)));
  await page.evaluate(() => {
    const span = document.createElement('span');
    span.textContent = 'Hello from shadow';
    span.addEventListener('click', () => window['clicked'] = true);
    document.querySelector('div').shadowRoot.appendChild(span);
  });
  await watchdog;
  expect(await page.evaluate(() => window['clicked'])).toBe(true);
});
it('should be atomic', async ({playwright, page}) => {
  const createDummySelector = () => ({
    query(root, selector) {
      const result = root.querySelector(selector);
      if (result)
        Promise.resolve().then(() => result.onclick = '');
      return result;
    },
    queryAll(root: HTMLElement, selector: string) {
      const result = Array.from(root.querySelectorAll(selector));
      for (const e of result)
        Promise.resolve().then(() => (e as HTMLElement).onclick = null);
      return result;
    }
  });
  await playwright.selectors.register('dispatchEvent', createDummySelector);
  await page.setContent(`
Hello
`);
  await page.dispatchEvent('dispatchEvent=div', 'click');
  expect(await page.evaluate(() => window['_clicked'])).toBe(true);
});
it('should dispatch drag drop events', async ({page, server}) => {
  await page.goto(server.PREFIX + '/drag-n-drop.html');
  const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
  await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
  await page.dispatchEvent('#target', 'drop', { dataTransfer });
  const source = await page.$('#source');
  const target = await page.$('#target');
  expect(await page.evaluate(({source, target}) => {
    return source.parentElement === target;
  }, {source, target})).toBeTruthy();
});
it('should dispatch drag drop events', async ({page, server}) => {
  await page.goto(server.PREFIX + '/drag-n-drop.html');
  const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
  const source = await page.$('#source');
  await source.dispatchEvent('dragstart', { dataTransfer });
  const target = await page.$('#target');
  await target.dispatchEvent('drop', { dataTransfer });
  expect(await page.evaluate(({source, target}) => {
    return source.parentElement === target;
  }, {source, target})).toBeTruthy();
});
it('should dispatch click event', async ({page, server}) => {
  await page.goto(server.PREFIX + '/input/button.html');
  const button = await page.$('button');
  await button.dispatchEvent('click');
  expect(await page.evaluate(() => window['result'])).toBe('Clicked');
});