/*
 * 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.
 */

package com.microsoft.playwright.assertions;

import java.util.regex.Pattern;

/**
 * The {@code PageAssertions} class provides assertion methods that can be used to make assertions about the {@code Page}
 * state in the tests.
 * <pre>{@code
 * // ...
 * import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
 *
 * public class TestPage {
 *   // ...
 *   @Test
 *   void navigatesToLoginPage() {
 *     // ...
 *     page.getByText("Sign in").click();
 *     assertThat(page).hasURL(Pattern.compile(".*\/login"));
 *   }
 * }
 * }</pre>
 */
public interface PageAssertions {
  class MatchesAriaSnapshotOptions {
    /**
     * Time to retry the assertion for in milliseconds. Defaults to {@code 5000}.
     */
    public Double timeout;

    /**
     * Time to retry the assertion for in milliseconds. Defaults to {@code 5000}.
     */
    public MatchesAriaSnapshotOptions setTimeout(double timeout) {
      this.timeout = timeout;
      return this;
    }
  }
  class HasTitleOptions {
    /**
     * Time to retry the assertion for in milliseconds. Defaults to {@code 5000}.
     */
    public Double timeout;

    /**
     * Time to retry the assertion for in milliseconds. Defaults to {@code 5000}.
     */
    public HasTitleOptions setTimeout(double timeout) {
      this.timeout = timeout;
      return this;
    }
  }
  class HasURLOptions {
    /**
     * Whether to perform case-insensitive match. {@code ignoreCase} option takes precedence over the corresponding regular
     * expression parameter if specified. A provided predicate ignores this flag.
     */
    public Boolean ignoreCase;
    /**
     * Time to retry the assertion for in milliseconds. Defaults to {@code 5000}.
     */
    public Double timeout;

    /**
     * Whether to perform case-insensitive match. {@code ignoreCase} option takes precedence over the corresponding regular
     * expression parameter if specified. A provided predicate ignores this flag.
     */
    public HasURLOptions setIgnoreCase(boolean ignoreCase) {
      this.ignoreCase = ignoreCase;
      return this;
    }
    /**
     * Time to retry the assertion for in milliseconds. Defaults to {@code 5000}.
     */
    public HasURLOptions setTimeout(double timeout) {
      this.timeout = timeout;
      return this;
    }
  }
  /**
   * Makes the assertion check for the opposite condition.
   *
   * <p> <strong>Usage</strong>
   *
   * <p> For example, this code tests that the page URL doesn't contain {@code "error"}:
   * <pre>{@code
   * assertThat(page).not().hasURL("error");
   * }</pre>
   *
   * @since v1.20
   */
  PageAssertions not();
  /**
   * Asserts that the page body matches the given <a href="https://playwright.dev/java/docs/aria-snapshots">accessibility
   * snapshot</a>.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * page.navigate("https://demo.playwright.dev/todomvc/");
   * assertThat(page).matchesAriaSnapshot("""
   *   - heading "todos"
   *   - textbox "What needs to be done?"
   * """);
   * }</pre>
   *
   * @since v1.60
   */
  default void matchesAriaSnapshot(String expected) {
    matchesAriaSnapshot(expected, null);
  }
  /**
   * Asserts that the page body matches the given <a href="https://playwright.dev/java/docs/aria-snapshots">accessibility
   * snapshot</a>.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * page.navigate("https://demo.playwright.dev/todomvc/");
   * assertThat(page).matchesAriaSnapshot("""
   *   - heading "todos"
   *   - textbox "What needs to be done?"
   * """);
   * }</pre>
   *
   * @since v1.60
   */
  void matchesAriaSnapshot(String expected, MatchesAriaSnapshotOptions options);
  /**
   * Ensures the page has the given title.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasTitle("Playwright");
   * }</pre>
   *
   * @param titleOrRegExp Expected title or RegExp.
   * @since v1.20
   */
  default void hasTitle(String titleOrRegExp) {
    hasTitle(titleOrRegExp, null);
  }
  /**
   * Ensures the page has the given title.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasTitle("Playwright");
   * }</pre>
   *
   * @param titleOrRegExp Expected title or RegExp.
   * @since v1.20
   */
  void hasTitle(String titleOrRegExp, HasTitleOptions options);
  /**
   * Ensures the page has the given title.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasTitle("Playwright");
   * }</pre>
   *
   * @param titleOrRegExp Expected title or RegExp.
   * @since v1.20
   */
  default void hasTitle(Pattern titleOrRegExp) {
    hasTitle(titleOrRegExp, null);
  }
  /**
   * Ensures the page has the given title.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasTitle("Playwright");
   * }</pre>
   *
   * @param titleOrRegExp Expected title or RegExp.
   * @since v1.20
   */
  void hasTitle(Pattern titleOrRegExp, HasTitleOptions options);
  /**
   * Ensures the page is navigated to the given URL.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasURL(".com");
   * }</pre>
   *
   * @param urlOrRegExp Expected URL string or RegExp.
   * @since v1.20
   */
  default void hasURL(String urlOrRegExp) {
    hasURL(urlOrRegExp, null);
  }
  /**
   * Ensures the page is navigated to the given URL.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasURL(".com");
   * }</pre>
   *
   * @param urlOrRegExp Expected URL string or RegExp.
   * @since v1.20
   */
  void hasURL(String urlOrRegExp, HasURLOptions options);
  /**
   * Ensures the page is navigated to the given URL.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasURL(".com");
   * }</pre>
   *
   * @param urlOrRegExp Expected URL string or RegExp.
   * @since v1.20
   */
  default void hasURL(Pattern urlOrRegExp) {
    hasURL(urlOrRegExp, null);
  }
  /**
   * Ensures the page is navigated to the given URL.
   *
   * <p> <strong>Usage</strong>
   * <pre>{@code
   * assertThat(page).hasURL(".com");
   * }</pre>
   *
   * @param urlOrRegExp Expected URL string or RegExp.
   * @since v1.20
   */
  void hasURL(Pattern urlOrRegExp, HasURLOptions options);
}

