/* Copyright 2014 Red Hat, Inc. and/or its affiliates. This file is part of darcy-ui. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.redhat.darcy.ui; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.redhat.darcy.ui.api.Context; import com.redhat.darcy.ui.api.Locator; import com.redhat.darcy.ui.api.View; import com.redhat.darcy.ui.api.WrapsElement; import com.redhat.darcy.ui.api.elements.Element; import com.redhat.darcy.ui.api.elements.Findable; import com.redhat.darcy.ui.internal.FindsByAttribute; import com.redhat.darcy.ui.internal.FindsById; import com.redhat.darcy.ui.internal.FindsByLinkText; import com.redhat.darcy.ui.internal.FindsByName; import com.redhat.darcy.ui.internal.FindsByNested; import com.redhat.darcy.ui.internal.FindsByPartialTextContent; import com.redhat.darcy.ui.internal.FindsByTextContent; import com.redhat.darcy.ui.internal.FindsByTitle; import com.redhat.darcy.ui.internal.FindsByView; import com.redhat.darcy.ui.internal.FindsByXPath; import com.redhat.darcy.ui.testing.doubles.AlwaysDisplayedLabel; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.Arrays; @RunWith(JUnit4.class) public class ByTest { @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByIdIfContextDoesNotSupportById() { Context mockContext = mock(Context.class); By.id("test").find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByIdIfContextDoesNotSupportById() { Context mockContext = mock(Context.class); By.id("test").findAll(Element.class, mockContext); } @Test public void shouldUseFindByIdToFindById() { FindsByAll mockContext = mock(FindsByAll.class); By.id("test").find(Element.class, mockContext); verify(mockContext).findById(Element.class, "test"); } @Test(expected = IllegalArgumentException.class) public void shouldThrowExceptionOnZeroLocators() { Locator locator = By.chained(new Locator[]{}); } @Test public void shouldUseFindByIdToFindAllById() { FindsByAll mockContext = mock(FindsByAll.class); By.id("test").findAll(Element.class, mockContext); verify(mockContext).findAllById(Element.class, "test"); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByXpathIfContextDoesNotSupportByXpath() { Context mockContext = mock(Context.class); By.xpath("test").find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByXpathIfContextDoesNotSupportByXpath() { Context mockContext = mock(Context.class); By.xpath("test").findAll(Element.class, mockContext); } @Test public void shouldUseFindByXpathToFindByXpath() { FindsByAll mockContext = mock(FindsByAll.class); By.xpath("test").find(Element.class, mockContext); verify(mockContext).findByXPath(Element.class, "test"); } @Test public void shouldUseFindByXpathToFindAllByXpath() { FindsByAll mockContext = mock(FindsByAll.class); By.xpath("test").findAll(Element.class, mockContext); verify(mockContext).findAllByXPath(Element.class, "test"); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByNameIfContextDoesNotSupportByName() { Context mockContext = mock(Context.class); By.name("test").find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByNameIfContextDoesNotSupportByName() { Context mockContext = mock(Context.class); By.name("test").findAll(Element.class, mockContext); } @Test public void shouldUseFindByNameToFindByName() { FindsByAll mockContext = mock(FindsByAll.class); By.name("test").find(Element.class, mockContext); verify(mockContext).findByName(Element.class, "test"); } @Test public void shouldUseFindByNameToFindAllByXpath() { FindsByAll mockContext = mock(FindsByAll.class); By.name("test").findAll(Element.class, mockContext); verify(mockContext).findAllByName(Element.class, "test"); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByAttributeIfContextDoesNotSupportByAttributeOrByXpath() { Context mockContext = mock(Context.class); By.attribute("value", "test").find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByAttributeIfContextDoesNotSupportByAttributeOrByXpath() { Context mockContext = mock(Context.class); By.attribute("value", "test").findAll(Element.class, mockContext); } @Test public void shouldUseFindByAttributeToFindByAttribute() { FindsByAll mockContext = mock(FindsByAll.class); By.attribute("value", "test").find(Element.class, mockContext); verify(mockContext).findByAttribute(Element.class, "value", "test"); } @Test public void shouldUseFindByAttributeToFindAllByAttribute() { FindsByAll mockContext = mock(FindsByAll.class); By.attribute("value", "test").findAll(Element.class, mockContext); verify(mockContext).findAllByAttribute(Element.class, "value", "test"); } @Test public void shouldUseFindAllByXPathIfContextDoesNotImplementFindsByAttribute() { FindsByAllExceptAttribute mockContext = mock(FindsByAllExceptAttribute.class); By.attribute("value", "test").findAll(Element.class, mockContext); verify(mockContext).findAllByXPath(Element.class, ".//*[@value='test']"); } @Test public void shouldUseFindByXPathIfContextDoesNotImplementFindsByAttribute() { FindsByAllExceptAttribute mockContext = mock(FindsByAllExceptAttribute.class); By.attribute("value", "test").find(Element.class, mockContext); verify(mockContext).findByXPath(Element.class, ".//*[@value='test']"); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByNestedIfContextDoesNotSupportByNested() { Context mockContext = mock(Context.class); Locator mockLocator = mock(Locator.class); Element mockElement = mock(Element.class); By.nested(mockElement, mockLocator).find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByNestedIfContextDoesNotSupportByNested() { Context mockContext = mock(Context.class); Locator mockLocator = mock(Locator.class); Element mockElement = mock(Element.class); By.nested(mockElement, mockLocator).findAll(Element.class, mockContext); } @Test public void shouldUseFindByNestedToFindByNested() { FindsByAll mockContext = mock(FindsByAll.class); Locator mockLocator = mock(Locator.class); Element mockElement = mock(Element.class); By.nested(mockElement, mockLocator).find(Element.class, mockContext); verify(mockContext).findByNested(Element.class, mockElement, mockLocator); } @Test public void shouldUseFindAllByNestedToFindByNested() { FindsByAll mockContext = mock(FindsByAll.class); Locator mockLocator = mock(Locator.class); Element mockElement = mock(Element.class); By.nested(mockElement, mockLocator).findAll(Element.class, mockContext); verify(mockContext).findAllByNested(Element.class, mockElement, mockLocator); } @Test public void shouldUnwrapWrappedElementsInByNested() { Element mockElement = mock(ElementWrapper.class); FindsByAll mockContext = mock(FindsByAll.class); Element realElement = new AlwaysDisplayedLabel(); when(((WrapsElement) mockElement).getWrappedElement()).thenReturn(realElement); new By.ByNested(mockElement, By.id("child")).find(Element.class, mockContext); verify(mockContext).findByNested(Element.class, realElement, By.id("child")); } @Test public void shouldUnwrapWrappedElementsInByNestedWhenFindingAll() { Element mockElement = mock(ElementWrapper.class); FindsByAll mockContext = mock(FindsByAll.class); Element realElement = new AlwaysDisplayedLabel(); when(((WrapsElement) mockElement).getWrappedElement()).thenReturn(realElement); new By.ByNested(mockElement, By.id("child")).findAll(Element.class, mockContext); verify(mockContext).findAllByNested(Element.class, realElement, By.id("child")); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByChainedIfContextDoesNotSupportByChained() { Context mockContext = mock(Context.class); Locator[] mockLocators = new Locator[] { mock(Locator.class), mock(Locator.class) }; By.chained(mockLocators).find(Element.class, mockContext); } @Test public void shouldAllowChainingLocatorsInByNested() { Element mockElement = mock(Element.class); FindsByAll mockContext = mock(FindsByAll.class); By.ByNested byNested = new By.ByNested(mockElement, By.id("first"), By.id("second")); byNested.find(Element.class, mockContext); verify(mockContext).findByNested(Element.class, mockElement, By.chained(By.id("first"), By.id("second"))); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByChainedIfContextDoesNotSupportByChained() { Context mockContext = mock(Context.class); Locator[] mockLocators = new Locator[] { mock(Locator.class), mock(Locator.class) }; By.chained(mockLocators).findAll(Element.class, mockContext); } @Test public void shouldUseFindByChainedToFindByChained() { FindsByAll mockContext = mock(FindsByAll.class); Locator[] mockLocators = new Locator[] { mock(Locator.class), mock(Locator.class) }; By.chained(mockLocators).find(Element.class, mockContext); verify(mockContext).findByChained(Element.class, mockLocators); } @Test public void shouldUseFindByChainedToFindByAllChained() { FindsByAll mockContext = mock(FindsByAll.class); Locator[] mockLocators = new Locator[] { mock(Locator.class), mock(Locator.class) }; By.chained(mockLocators).findAll(Element.class, mockContext); verify(mockContext).findAllByChained(Element.class, mockLocators); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByLinkTextIfContextDoesNotSupportByLinkText() { Context mockContext = mock(Context.class); By.linkText("test").find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByLinkTextIfContextDoesNotSupportByLinkText() { Context mockContext = mock(Context.class); By.linkText("test").findAll(Element.class, mockContext); } @Test public void shouldUseFindByLinkTextToFindByLinkText() { FindsByAll mockContext = mock(FindsByAll.class); By.linkText("test").find(Element.class, mockContext); verify(mockContext).findByLinkText(Element.class, "test"); } @Test public void shouldUseFindAllByLinkTextToFindAllByLinkText() { FindsByAll mockContext = mock(FindsByAll.class); By.linkText("test").findAll(Element.class, mockContext); verify(mockContext).findAllByLinkText(Element.class, "test"); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByTextContentIfContextDoesNotSupportByTextContent() { Context mockContext = mock(Context.class); By.textContent("test").find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByTextContentIfContextDoesNotSupportByTextContent() { Context mockContext = mock(Context.class); By.textContent("test").findAll(Element.class, mockContext); } @Test public void shouldUseFindByTextContentToFindByTextContent() { FindsByAll mockContext = mock(FindsByAll.class); By.textContent("test").find(Element.class, mockContext); verify(mockContext).findByTextContent(Element.class, "test"); } @Test public void shouldUseFindAllByTextContentToFindAllByTextContent() { FindsByAll mockContext = mock(FindsByAll.class); By.textContent("test").findAll(Element.class, mockContext); verify(mockContext).findAllByTextContent(Element.class, "test"); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByPartialTextContentIfContextDoesNotSupportByPartialTextContent() { Context mockContext = mock(Context.class); By.partialTextContent("test").find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByPartialTextContentIfContextDoesNotSupportByPartialTextContent() { Context mockContext = mock(Context.class); By.partialTextContent("test").findAll(Element.class, mockContext); } @Test public void shouldUseFindByPartialTextContentToFindByPartialTextContent() { FindsByAll mockContext = mock(FindsByAll.class); By.partialTextContent("test").find(Element.class, mockContext); verify(mockContext).findByPartialTextContent(Element.class, "test"); } @Test public void shouldUseFindAllByPartialTextContentToFindAllByPartialTextContent() { FindsByAll mockContext = mock(FindsByAll.class); By.partialTextContent("test").findAll(Element.class, mockContext); verify(mockContext).findAllByPartialTextContent(Element.class, "test"); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindByViewIfContextDoesNotSupportByView() { Context mockContext = mock(Context.class); View mockView = mock(View.class); By.view(mockView).find(Element.class, mockContext); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionForFindAllByViewIfContextDoesNotSupportByView() { Context mockContext = mock(Context.class); View mockView = mock(View.class); By.view(mockView).findAll(Element.class, mockContext); } @Test public void shouldUseFindByViewToFindByView() { FindsByAll mockContext = mock(FindsByAll.class); View mockView = mock(View.class); By.view(mockView).find(Element.class, mockContext); verify(mockContext).findByView(Element.class, mockView); } @Test public void shouldUseFindAllByViewToFindAllByView() { FindsByAll mockContext = mock(FindsByAll.class); View mockView = mock(View.class); By.view(mockView).findAll(Element.class, mockContext); verify(mockContext).findAllByView(Element.class, mockView); } @Test public void shouldHaveEquivalentByIdLocators() { By.ById byId_test_ = By.id("test"); assertThat(byId_test_, not(equalTo(By.name("test")))); assertThat(byId_test_, equalTo(By.id("test"))); assertThat(byId_test_, not(equalTo(By.id("anotherTest")))); assertThat(byId_test_, equalTo(byId_test_)); assertThat(byId_test_.hashCode(), equalTo(By.id("test").hashCode())); } @Test public void shouldHaveEquivalentByNameLocators() { By.ByName byName_test_ = By.name("test"); assertThat(byName_test_, not(equalTo(By.id("test")))); assertThat(byName_test_, equalTo(By.name("test"))); assertThat(byName_test_, not(equalTo(By.name("anotherTest")))); assertThat(byName_test_, equalTo(byName_test_)); assertThat(byName_test_.hashCode(), equalTo(By.name("test").hashCode())); } @Test public void shouldHaveEquivalentByLinkTestLocators() { By.ByLinkText byLinkText_test_ = By.linkText("test"); assertThat(byLinkText_test_, not(equalTo(By.name("testing")))); assertThat(byLinkText_test_, equalTo(By.linkText("test"))); assertThat(byLinkText_test_, not(equalTo(By.linkText("anotherTest")))); assertThat(byLinkText_test_, equalTo(byLinkText_test_)); assertThat(byLinkText_test_.hashCode(), equalTo(By.linkText("test").hashCode())); } @Test public void shouldHaveEquivalentByTextContentLocators() { By.ByTextContent byTextContent_test_ = By.textContent("test"); assertThat(byTextContent_test_, not(equalTo(By.name("testing")))); assertThat(byTextContent_test_, equalTo(By.textContent("test"))); assertThat(byTextContent_test_, not(equalTo(By.textContent("anotherTest")))); assertThat(byTextContent_test_, equalTo(byTextContent_test_)); assertThat(byTextContent_test_.hashCode(), equalTo(By.textContent("test").hashCode())); } @Test public void shouldHaveEquivalentByPartialTextContentLocators() { By.ByPartialTextContent byPartialTextContent_test_ = By.partialTextContent("test"); assertThat(byPartialTextContent_test_, not(equalTo(By.name("testing")))); assertThat(byPartialTextContent_test_, equalTo(By.partialTextContent("test"))); assertThat(byPartialTextContent_test_, not(equalTo(By.partialTextContent("anotherTest")))); assertThat(byPartialTextContent_test_, equalTo(byPartialTextContent_test_)); assertThat(byPartialTextContent_test_.hashCode(), equalTo(By.partialTextContent ("test").hashCode())); } @Test public void shouldHaveEquivalentByXpathLocators() { By.ByXPath byXPath_test_ = By.xpath("test"); assertThat(byXPath_test_, not(equalTo(By.name("testing")))); assertThat(byXPath_test_, equalTo(By.xpath("test"))); assertThat(byXPath_test_, not(equalTo(By.xpath("anotherTest")))); assertThat(byXPath_test_, equalTo(byXPath_test_)); assertThat(byXPath_test_.hashCode(), equalTo(By.xpath("test").hashCode())); } @Test public void shouldHaveByAttributeEquivalence() { By.ByAttribute byAttribute_attributeTest_valueTest_ = By.attribute("attributeTest", "valueTest"); assertThat(byAttribute_attributeTest_valueTest_, not(equalTo(By.id("test")))); assertThat(byAttribute_attributeTest_valueTest_, equalTo(By.attribute("attributeTest", "valueTest"))); assertThat(byAttribute_attributeTest_valueTest_, not(equalTo(By.attribute("1", "2")))); assertThat(byAttribute_attributeTest_valueTest_, equalTo(byAttribute_attributeTest_valueTest_)); assertThat(byAttribute_attributeTest_valueTest_.hashCode(), equalTo(By.attribute("attributeTest", "valueTest").hashCode())); } @Test public void shouldHaveByViewEquivalence() { View testView = mock(View.class); View differentTestView = mock(View.class); By.ByView byView_testView_ = By.view(testView); assertThat(byView_testView_, not(equalTo(By.id("test")))); assertThat(byView_testView_, equalTo(By.view(testView))); assertThat(byView_testView_, not(equalTo(By.view(differentTestView)))); assertThat(byView_testView_, equalTo(byView_testView_)); assertThat(byView_testView_.hashCode(), equalTo(By.view(testView).hashCode())); } @Test public void shouldCorrectlyImplementEqualsForByNested() { Element parent = new AlwaysDisplayedLabel(); Element differentParent = new AlwaysDisplayedLabel(); By.ByNested nestedUnderParentByNameTest = By.nested(parent, By.name("test")); assertEquals(nestedUnderParentByNameTest, By.nested(parent, By.name("test"))); assertEquals(nestedUnderParentByNameTest, nestedUnderParentByNameTest); assertNotEquals(nestedUnderParentByNameTest, By.nested(parent, By.id("id"))); assertNotEquals(nestedUnderParentByNameTest, By.nested(differentParent, By.name("test"))); assertNotEquals(nestedUnderParentByNameTest, By.id("something else entirely")); assertEquals(nestedUnderParentByNameTest.hashCode(), By.nested(parent, By.name("test")).hashCode()); } @Test public void shouldCorrectlyImplementEqualsForByChained() { Locator idOf_parent_ = By.id("parent"); Locator nameOf_child_ = By.name("child"); By.ByChained underId_parent_andName_child_ = By.chained(idOf_parent_, nameOf_child_); assertEquals(underId_parent_andName_child_, By.chained(By.id("parent"), By.name("child"))); assertEquals(underId_parent_andName_child_, underId_parent_andName_child_); assertNotEquals(underId_parent_andName_child_, By.chained(By.id("parent"), By.id("diff"))); assertNotEquals(underId_parent_andName_child_, By.chained(By.name("diff"), By.name("child"))); assertNotEquals(underId_parent_andName_child_, By.id("something else entirely")); assertEquals(underId_parent_andName_child_.hashCode(), By.chained(By.id("parent"), By.name("child")).hashCode()); } @Test public void shouldCorrectlyImplementEqualsForByTitle() { By.ByTitle byTitleFoo = By.title("foo"); assertEquals(byTitleFoo, By.title("foo")); assertEquals(byTitleFoo, byTitleFoo); assertNotEquals(byTitleFoo, By.title("bar")); assertEquals(byTitleFoo.hashCode(), By.title("foo").hashCode()); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionWhenTryingToFindByTitleWhenNotSupported() { Context context = mock(Context.class); By.title("foo").find(Findable.class, context); } @Test(expected = LocatorNotSupportedException.class) public void shouldThrowLocatorNotSupportedExceptionWhenTryingToFindAllByTitleWhenNotSupported() { Context context = mock(Context.class); By.title("foo").findAll(Findable.class, context); } @Test public void shouldFindByTitleWhenUsingFindByTitle() { FindsByAll mockContext = mock(FindsByAll.class); Element el = mock(Element.class); when(mockContext.findByTitle(Element.class, "foo")).thenReturn(el); assertSame(el, By.title("foo").find(Element.class, mockContext)); } @Test public void shouldFindAllByTitleWhenUsingFindAllByTitle() { FindsByAll mockContext = mock(FindsByAll.class); Element el1 = mock(Element.class); Element el2 = mock(Element.class); when(mockContext.findAllByTitle(Element.class, "foo")).thenReturn(Arrays.asList(el1, el2)); assertThat(By.title("foo").findAll(Element.class, mockContext), contains(sameInstance(el1), sameInstance(el2))); } interface FindsByAll extends Context, FindsByAttribute, FindsById, FindsByXPath, FindsByName, FindsByNested, FindsByLinkText, FindsByPartialTextContent, FindsByTextContent, FindsByView, FindsByTitle {} interface FindsByAllExceptAttribute extends Context, FindsById, FindsByXPath, FindsByName, FindsByNested, FindsByLinkText, FindsByPartialTextContent, FindsByTextContent, FindsByView, FindsByTitle {} interface ElementWrapper extends Element, WrapsElement {}; }