/* 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.internal; import static org.junit.Assert.assertSame; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.redhat.darcy.ui.NullContextException; import com.redhat.darcy.ui.api.ElementContext; import com.redhat.darcy.ui.api.HasElementContext; import com.redhat.darcy.ui.api.Locator; 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.api.elements.TextInput; import com.redhat.darcy.ui.testing.doubles.DummyContext; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.lang.reflect.Method; @RunWith(JUnit4.class) public class ElementHandlerTest { Method setContext; DummyContext mockContext; ElementHandler handler; Element mockElement; Locator mockLocator; @Before public void setup() throws NoSuchMethodException { setContext = HasElementContext.class.getMethod("setContext", ElementContext.class); mockContext = mock(DummyContext.class); mockElement = mock(Element.class); mockLocator = mock(Locator.class); when(mockLocator.find(anyObject(), anyObject())).thenReturn(mockElement); handler = new ElementHandler(TextInput.class, mockLocator); } @Test public void shouldImplementSetContextAndUseContextToLookupElement() throws Throwable { // This should set the mock context to be used later handler.invoke(null, setContext, new Object[] { mockContext }); // This should cause the context to be used to find the element if it was properly set handler.invoke(null, Element.class.getMethod("isDisplayed"), new Object[] {}); // Verify the context was used verify(mockLocator).find(anyObject(), eq(mockContext)); } @Test public void shouldLookupElementWithAppropriateType() throws Throwable { // This should set the mock context to be used later handler.invoke(null, setContext, new Object[] { mockContext }); // This should cause the context to be used to find the element if it was properly set handler.invoke(null, Element.class.getMethod("isDisplayed"), new Object[] {}); // Verify the mock was used verify(mockLocator).find(eq(TextInput.class), anyObject()); } @Test public void shouldForwardMethodsToFoundElement() throws Throwable { // This should set the mock context to be used later handler.invoke(null, setContext, new Object[] { mockContext }); // This should cause the context to be used to find the element if it was properly set handler.invoke(null, Findable.class.getMethod("isPresent"), new Object[] {}); verify(mockElement).isPresent(); } @Test public void shouldCacheAndReuseFoundElement() throws Throwable { // This should set the mock context to be used later handler.invoke(null, setContext, new Object[] { mockContext }); // This should cause the context to be used to find the element if it was properly set handler.invoke(null, Element.class.getMethod("isDisplayed"), new Object[] {}); handler.invoke(null, Element.class.getMethod("isDisplayed"), new Object[] {}); verify(mockLocator, times(1)).find(anyObject(), anyObject()); } @Test(expected = TestException.class) public void shouldThrowCauseOfInvocationTargetExceptions() throws Throwable { when(mockElement.isDisplayed()).thenThrow(new TestException()); // This should set the mock context to be used later handler.invoke(null, setContext, new Object[]{mockContext}); // This should cause the context to be used to find the element if it was properly set handler.invoke(null, Element.class.getMethod("isDisplayed"), new Object[]{}); } @Test(expected = NullContextException.class) public void shouldThrowNullContextExceptionIfMethodIsCalledWithoutAContextBeingSet() throws Throwable { handler.invoke(null, Element.class.getMethod("isDisplayed"), new Object[] {}); } @Test public void shouldImplementWrapsElement() throws Throwable { handler.invoke(null, setContext, new Object[] { mockContext }); Object element = handler.invoke(null, WrapsElement.class.getMethod("getWrappedElement"), new Object[]{}); assertSame(mockElement, element); } private class TestException extends RuntimeException {} }