package integration;

import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.ex.ElementNotFound;
import com.codeborne.selenide.ex.TextsMismatch;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.InvalidSelectorException;

import static com.codeborne.selenide.CollectionCondition.empty;
import static com.codeborne.selenide.CollectionCondition.*;
import static com.codeborne.selenide.Condition.*;
import static com.codeborne.selenide.Selectors.byText;
import static com.codeborne.selenide.Selenide.*;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class CollectionMethodsTest extends IntegrationTest {
  @Before
  public void openTestPageWithJQuery() {
    openFile("page_with_selects_without_jquery.html");
  }

  @Test
  public void useTwoDollarsToGetListOfElements() {
    $$("#radioButtons input").shouldHave(size(4));
    getElements(By.cssSelector("#radioButtons input")).shouldHave(size(4));

    $("#radioButtons").$$("input").shouldHave(size(4));
    $("#radioButtons").$$(By.tagName("input")).shouldHave(size(4));
    $("#radioButtons").findAll("input").shouldHave(size(4));
    $("#radioButtons").findAll(By.tagName("input")).shouldHave(size(4));
  }

  @Test(expected = InvalidSelectorException.class)
  public void invalidSelector() {
    $$(By.xpath("//xxx[@'")).shouldHave(size(0));
  }

  @Test
  public void canUseSizeMethod() {
    assertEquals(1, $$(By.name("domain")).size());
    assertEquals(1, $$("#theHiddenElement").size());
    assertEquals(4, $$("#radioButtons input").size());
    assertEquals(4, $$(By.xpath("//select[@name='domain']/option")).size());
    assertEquals(0, $$(By.name("non-existing-element")).size());
  }

  @Test
  public void canCheckIfCollectionIsEmpty() {
    $$(By.name("#dynamic-content-container span")).shouldBe(empty);
    $$(By.name("non-existing-element")).shouldBe(empty);
    $$(byText("Loading...")).shouldBe(empty);
  }

  @Test
  public void canCheckSizeOfCollection() {
    $$(By.name("domain")).shouldHaveSize(1);
    $$("#theHiddenElement").shouldHaveSize(1);
    $$("#radioButtons input").shouldHaveSize(4);
    $$(By.xpath("//select[@name='domain']/option")).shouldHaveSize(4);
    $$(By.name("non-existing-element")).shouldHaveSize(0);
    $$("#dynamic-content-container span").shouldHave(size(2));
  }

  @Test
  public void shouldWaitUntilCollectionGetsExpectedSize() {
    ElementsCollection spans = $$("#dynamic-content-container span");

    spans.shouldHave(size(2)); // appears after 2 seconds

    assertEquals(2, spans.size());
    assertArrayEquals(new String[]{"dynamic content", "dynamic content2"}, spans.getTexts());
  }

  @Test
  public void canCheckThatElementsHaveCorrectTexts() {
    $$("#dynamic-content-container span").shouldHave(
        texts("dynamic content", "dynamic content2"),
        texts("mic cont", "content2"),
        exactTexts("dynamic content", "dynamic content2"));
  }

  @Test
  public void ignoresWhitespacesInTexts() {
    $$("#dynamic-content-container span").shouldHave(
        texts("   dynamic \ncontent ", "dynamic \t\t\tcontent2\t\t\r\n"),
        exactTexts("dynamic \t\n content\n\r", "    dynamic content2      "));
  }

  @Test(expected = TextsMismatch.class)
  public void canCheckThatElementsHaveExactlyCorrectTexts() {
    $$("#dynamic-content-container span").shouldHave(
        exactTexts("content", "content2"));
  }

  @Test(expected = ElementNotFound.class)
  public void textsCheckThrowsElementNotFound() {
    $$(".non-existing-elements").shouldHave(texts("content1", "content2"));
  }

  @Test(expected = ElementNotFound.class)
  public void exactTextsCheckThrowsElementNotFound() {
    $$(".non-existing-elements").shouldHave(exactTexts("content1", "content2"));
  }

  @Test(expected = TextsMismatch.class)
  public void textsCheckThrowsTextsMismatch() {
    $$("#dynamic-content-container span").shouldHave(texts("static-content1", "static-content2", "static3"));
  }

  @Test
  public void userCanFilterOutMatchingElements() {
    $$("#multirowTable tr").shouldHaveSize(2);
    $$("#multirowTable tr").filterBy(text("Norris")).shouldHaveSize(1);
    $$("#multirowTable tr").filterBy(cssClass("inexisting")).shouldHaveSize(0);
  }

  @Test
  public void userCanExcludeMatchingElements() {
    $$("#multirowTable tr").shouldHaveSize(2);
    $$("#multirowTable tr").excludeWith(text("Chack")).shouldHaveSize(0);
    $$("#multirowTable tr").excludeWith(cssClass("inexisting")).shouldHaveSize(2);
  }

  @Test
  public void userCanFindMatchingElementFromList() {
    $$("#multirowTable tr").findBy(text("Norris")).shouldHave(text("Norris"));
  }

  @Test
  public void findWaitsUntilElementMatches() {
    $$("#dynamic-content-container span").findBy(text("dynamic content2")).shouldBe(visible);
    $$("#dynamic-content-container span").findBy(text("unexisting")).shouldNot(exist);
  }

  @Test
  public void collectionMethodsCanBeChained() {
    $$("#multirowTable tr").shouldHave(size(2))
        .filterBy(text("Norris")).shouldHave(size(1));
  }

  @Test
  public void shouldMethodsCanCheckMultipleConditions() {
    $$("#multirowTable tr td").shouldHave(size(4), texts("Chack", "Norris", "Chack", "L'a Baskerville"));
  }

  @Test
  public void toStringPrintsOutLastFetchedElements() {
    assertEquals("[\n" +
        "\t<textarea id=text-area type=textarea></textarea>\n" +
        "]", $$("#text-area").toString());
  }

  @Test
  public void toStringFetchedCollectionFromWebdriverIfNotFetchedYet() {
    ElementsCollection collectionWithFetchedElements = $$("#text-area").shouldHave(texts("This is text area"));
    
    assertEquals("[\n" +
        "\t<textarea id=text-area value=This is text area type=textarea>This is text area</textarea>\n" +
        "]", collectionWithFetchedElements.toString());
  }

  @Test
  public void toStringPrintsErrorIfFailedToFetchElements() {
    String actual = $$(By.xpath("\\")).toString();
    
    assertTrue("Actual text: " + actual, actual.matches("\\[InvalidSelectorException:.*\\]"));
  }
}

@@ -672,51 +672,8 @@
 als;
-%0Aimport static org.junit.Assert.assertTrue;
 %0A%0Apu
@@ -5294,822 +5294,7 @@
 %0A  %7D
-%0A%0A  @Test%0A  public void toStringPrintsOutLastFetchedElements() %7B%0A    assertEquals(%22%5B%5Cn%22 +%0A        %22%5Ct%3Ctextarea id=text-area type=textarea%3E%3C/textarea%3E%5Cn%22 +%0A        %22%5D%22, $$(%22#text-area%22).toString());%0A  %7D%0A%0A  @Test%0A  public void toStringFetchedCollectionFromWebdriverIfNotFetchedYet() %7B%0A    ElementsCollection collectionWithFetchedElements = $$(%22#text-area%22).shouldHave(texts(%22This is text area%22));%0A    %0A    assertEquals(%22%5B%5Cn%22 +%0A        %22%5Ct%3Ctextarea id=text-area value=This is text area type=textarea%3EThis is text area%3C/textarea%3E%5Cn%22 +%0A        %22%5D%22, collectionWithFetchedElements.toString());%0A  %7D%0A%0A  @Test%0A  public void toStringPrintsErrorIfFailedToFetchElements() %7B%0A    String actual = $$(By.xpath(%22%5C%5C%22)).toString();%0A    %0A    assertTrue(%22Actual text: %22 + actual, actual.matches(%22%5C%5C%5BInvalidSelectorException:.*%5C%5C%5D%22));%0A  %7D
 %0A%7D%0A

replace UI test by unit-test