@Test
  public void testEquals() {
    ElementLocator locator = mock(ElementLocator.class);
    when(locator.findElement()).thenReturn(element1);

    WebElement webElement = LocatorProxies.createWebElement(locator);
    WebElement sameWebElement = LocatorProxies.createWebElement(locator);

    assertThat(webElement).isEqualTo(sameWebElement);

    ElementLocator otherLocator = mock(ElementLocator.class);
    when(otherLocator.findElement()).thenReturn(element2);
    WebElement otherWebElement = LocatorProxies.createWebElement(otherLocator);

    assertThat(webElement).isNotEqualTo(otherWebElement);

    assertThat(LocatorProxies.loaded(webElement)).isFalse();
    assertThat(LocatorProxies.loaded(sameWebElement)).isFalse();
    assertThat(LocatorProxies.loaded(otherWebElement)).isFalse();

    LocatorProxies.now(webElement);

    assertThat(webElement).isEqualTo(sameWebElement);

    assertThat(LocatorProxies.loaded(webElement)).isTrue();
    assertThat(LocatorProxies.loaded(sameWebElement)).isTrue();
    assertThat(LocatorProxies.loaded(otherWebElement)).isFalse();

    LocatorProxies.reset(webElement);
    LocatorProxies.reset(sameWebElement);
    LocatorProxies.reset(otherWebElement);

    assertThat(LocatorProxies.loaded(webElement)).isFalse();
    assertThat(LocatorProxies.loaded(sameWebElement)).isFalse();
    assertThat(LocatorProxies.loaded(otherWebElement)).isFalse();

    LocatorProxies.now(webElement);

    assertThat(sameWebElement).isEqualTo(webElement);

    assertThat(LocatorProxies.loaded(webElement)).isTrue();
    assertThat(LocatorProxies.loaded(sameWebElement)).isTrue();
    assertThat(LocatorProxies.loaded(otherWebElement)).isFalse();

    assertThat(webElement).isNotEqualTo(otherWebElement);

    assertThat(LocatorProxies.loaded(otherWebElement)).isTrue();
  }
  @Test
  public void testStateElement() {
    ElementLocator locator = mock(ElementLocator.class);
    when(locator.findElement()).thenReturn(element1);

    WebElement webElement = LocatorProxies.createWebElement(locator);

    assertThat(LocatorProxies.present(webElement)).isTrue();
    webElement.isEnabled();

    when(element1.isEnabled()).thenThrow(StaleElementReferenceException.class);

    assertThat(LocatorProxies.present(webElement)).isFalse();

    reset(element1);
    when(element1.isEnabled()).thenThrow(StaleElementReferenceException.class);

    assertThatThrownBy(
            new ThrowableAssert.ThrowingCallable() {
              @Override
              public void call() throws Throwable {
                webElement.isEnabled();
              }
            })
        .isExactlyInstanceOf(StaleElementReferenceException.class);

    verify(element1, times(6)).isEnabled();
  }
  @Test
  public void testIsPresent() {
    ElementLocator locator = mock(ElementLocator.class);
    when(locator.findElement()).thenReturn(element1);
    when(locator.findElements()).thenReturn(Arrays.asList(element1, element2, element3));

    WebElement webElement = LocatorProxies.createWebElement(locator);

    ElementLocator otherLocator = mock(ElementLocator.class);
    WebElement otherWebElement = LocatorProxies.createWebElement(otherLocator);

    assertThat(LocatorProxies.loaded(webElement)).isFalse();
    assertThat(LocatorProxies.present(webElement)).isTrue();
    assertThat(LocatorProxies.loaded(webElement)).isTrue();

    assertThat(LocatorProxies.loaded(otherWebElement)).isFalse();
    assertThat(LocatorProxies.present(otherWebElement)).isFalse();
    assertThat(LocatorProxies.loaded(otherWebElement)).isFalse();

    List<WebElement> webElementList = LocatorProxies.createWebElementList(locator);

    assertThat(LocatorProxies.loaded(webElementList)).isFalse();
    assertThat(LocatorProxies.present(webElementList)).isTrue();
    assertThat(LocatorProxies.loaded(webElementList)).isTrue();

    when(locator.findElements()).thenReturn(Collections.<WebElement>emptyList());

    LocatorProxies.reset(webElementList);

    assertThat(LocatorProxies.loaded(webElementList)).isFalse();
    assertThat(LocatorProxies.present(webElementList)).isFalse();
    assertThat(LocatorProxies.loaded(webElementList)).isTrue();
  }
  @Test
  public void testHashcode() {
    ElementLocator locator = mock(ElementLocator.class);
    when(locator.findElement()).thenReturn(element1);

    WebElement webElement = LocatorProxies.createWebElement(locator);
    assertThat(webElement.hashCode()).isEqualTo(2048 + locator.hashCode());

    assertThat(LocatorProxies.loaded(webElement)).isFalse();

    LocatorProxies.now(webElement);

    assertThat(webElement.hashCode()).isEqualTo(element1.hashCode());
  }
  @Test
  public void testToString() {
    when(element1.toString()).thenReturn("element1");

    ElementLocator locator = mock(ElementLocator.class);
    when(locator.findElement()).thenReturn(element1);
    when(locator.toString()).thenReturn("element1-locator");

    WebElement webElement = LocatorProxies.createWebElement(locator);
    assertThat(webElement.toString()).isEqualTo("element1-locator (Lazy Element)");

    assertThat(LocatorProxies.loaded(webElement)).isFalse();

    LocatorProxies.now(webElement);

    assertThat(webElement.toString()).isEqualTo("element1-locator (" + element1.toString() + ")");
  }