/**
 * Copyright 2017 Google Inc. All rights reserved.
 * Modifications copyright (c) Microsoft Corporation.
 *
 * 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 type { Page } from '@playwright/test';
import { test as it, expect, rafraf } from './pageTest';
const giveItAChanceToResolve = (page: Page) => rafraf(page, 5);
it('element state checks should work as expected for label with zero-sized input', async ({ page, server }) => {
  await page.setContent(`
    
      Click me
       
  `);
  // Visible checks the label.
  expect(await page.isVisible('text=Click me')).toBe(true);
  expect(await page.isHidden('text=Click me')).toBe(false);
  // Enabled checks the input.
  expect(await page.isEnabled('text=Click me')).toBe(false);
  expect(await page.isDisabled('text=Click me')).toBe(true);
});
it('should wait for enclosing disabled button', async ({ page }) => {
  await page.setContent('Target 
Target Target 
');
  await page.$eval('div', div => {
    const root = div.attachShadow({ mode: 'open' });
    const label = document.createElement('label');
    label.setAttribute('for', 'target');
    label.textContent = 'Click me';
    root.appendChild(label);
    const input = document.createElement('input');
    input.setAttribute('type', 'checkbox');
    input.setAttribute('id', 'target');
    root.appendChild(input);
  });
  await page.check('label');
  expect(await page.$eval('input', input => input.checked)).toBe(true);
});
it('setInputFiles should work with label', async ({ page, asset }) => {
  await page.setContent(`Choose a file Text ${dom} `;
const domLabelFor = (dom: string, options?: Options) => `Text Button ${dom} `;
const domInLink = (dom: string, options?: Options) => `Button ${dom} `;
it('enabled/disabled retargeting', async ({ page, asset }) => {
  const cases = [
    { dom: domInLabel(`content `), visible: true, locator: 'label' },
    { dom: domInLabel(`content `), visible: true, locator: 'label' },
    { dom: domLabelFor(`content `), visible: true, locator: 'label' },
    { dom: domLabelFor(`content `), visible: true, locator: 'label' },
    { dom: domStandalone(`content `), visible: true, locator: 'span' },
    { dom: domInButton(`content `), visible: true, locator: 'span' },
    { dom: domInLink(`content `), visible: true, locator: 'span' },
    { dom: domInLabel(`content `, { hidden: true }), visible: false, locator: 'label' },
    { dom: domLabelFor(`content `, { hidden: true }), visible: false, locator: 'label' },
    { dom: domStandalone(`content `), visible: false, locator: 'span' },
    { dom: domInButton(`content `), visible: false, locator: 'span' },
    { dom: domInButton(`content `, { hidden: true }), visible: false, locator: 'span' },
    { dom: domInLink(`content `), visible: false, locator: 'span' },
    { dom: domInLink(`content `, { hidden: true }), visible: false, locator: 'span' },
  ];
  for (const { dom, visible, locator } of cases) {
    await it.step(`"${locator}" in "${dom}" should be visible=${visible}`, async () => {
      await page.setContent(dom);
      const target = page.locator(locator);
      const handle = (await page.$(locator))!;
      expect(await target.isVisible()).toBe(visible);
      expect(await target.isHidden()).toBe(!visible);
      if (visible) {
        await expect(target).toBeVisible();
        await expect(target).not.toBeHidden();
        await handle.waitForElementState('visible');
      } else {
        await expect(target).not.toBeVisible();
        await expect(target).toBeHidden();
        await handle.waitForElementState('hidden');
      }
    });
  }
});
it('editable retargeting', async ({ page, asset }) => {
  const cases = [
    { dom: domInLabel(`content
`), locator: 'div' },
    { dom: domInButton(`content
`), locator: 'div' },
    { dom: domInLink(`content
`), locator: 'div' },
    { dom: domInButton(`content
`), locator: 'div' },
  ];
  for (const { dom, locator } of cases) {
    await it.step(`"${locator}" in "${dom}" text selection`, async () => {
      await page.setContent(dom);
      const target = page.locator(locator);
      const handle = (await page.$(locator))!;
      expect(await target.isEditable()).toBe(true);
      expect(await handle.isEditable()).toBe(true);
      await expect(page.locator('#target')).toHaveText('content');
      await target.fill('foo');
      await expect(page.locator('#target')).toHaveText('foo');
      await target.selectText();
      if (browserName === 'firefox') {
        expect(await page.$eval('#target', target => {
          const selection = window.getSelection()!;
          return selection.anchorNode === target && selection.focusNode === target;
        })).toBe(true);
      } else {
        expect(await page.evaluate(() => window.getSelection()!.toString())).toBe('foo');
      }
    });
  }
});
it('select options retargeting', async ({ page }) => {
  const cases = [
    { dom: domInLabel(`Dog Cat Dog Cat Dog Cat Dog Cat Dog Cat Dog Cat content
content
content
`), locator: 'div' },
    { dom: domInButton(`content
`), locator: 'div' },
    { dom: domInLink(`content
`), locator: 'div' },
    { dom: domInButton(`content
`), locator: 'div' },
  ];
  for (const { dom, locator } of cases) {
    await it.step(`"${locator}" in "${dom}" direct actions`, async () => {
      await page.setContent(dom);
      const target = page.locator(locator);
      expect(await target.innerText()).toBe('content');
      expect(await target.textContent()).toBe('content');
      await expect(target).toHaveText('content');
      await expect(target).toContainText('content');
      await expect(target).not.toBeFocused();
      await expect(target).toHaveCount(1);
      await page.$eval('div', div => (div as any).foo = 'bar');
      await expect(target).toHaveJSProperty('foo', 'bar');
      await page.$eval('div', div => div.classList.add('cls'));
      await expect(target).toHaveClass('cls');
      await page.$eval('div', div => div.id = 'myid');
      await expect(target).toHaveId('myid');
      await expect(target).toHaveAttribute('id', 'myid');
      expect(await target.getAttribute('id')).toBe('myid');
    });
  }
});
it('check retargeting', async ({ page, asset }) => {
  const cases = [
    { dom: domInLabel(`TextTarget  
  `);
  await page.locator('a').click();
  expect(await page.evaluate('window.__clicked')).toBe(1);
  await page.setContent(`
    TextTarget  
  `);
  await page.locator('a').click();
  expect(await page.evaluate('window.__clicked')).toBe(2);
});