/*
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.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.redhat.darcy.ui.annotations.Context;
import com.redhat.darcy.ui.annotations.NotRequired;
import com.redhat.darcy.ui.annotations.Require;
import com.redhat.darcy.ui.annotations.RequireAll;
import com.redhat.darcy.ui.api.Locator;
import com.redhat.darcy.ui.api.ViewElement;
import com.redhat.darcy.ui.api.elements.Element;
import com.redhat.darcy.ui.api.elements.Findable;
import com.redhat.darcy.ui.testing.doubles.AlwaysDisplayedLabel;
import com.redhat.darcy.ui.testing.doubles.NeverDisplayedElement;
import com.redhat.darcy.ui.testing.doubles.NeverFoundElement;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.ArrayList;
import java.util.List;
@RunWith(JUnit4.class)
public class AbstractViewElementIsDisplayedTest {
@Test(expected = NoRequiredElementsException.class)
public void shouldThrowNoRequiredElementsExceptionIfCalledWithoutAnyAnnotatedElements() {
ViewElement testView = new AbstractViewElement(mock(Locator.class)) {
Element element = new AlwaysDisplayedLabel();
};
testView.isDisplayed();
}
@Test
public void shouldReturnTrueIfAllRequiredElementsAreDisplayed() {
ViewElement testView = new AbstractViewElement(mock(Locator.class)) {
@Require
private Element test = new AlwaysDisplayedLabel();
};
assertTrue("isDisplayed should return true if all required elements are displayed.",
testView.isDisplayed());
}
@Test
public void shouldReturnFalseIfNotAllRequiredElementsAreDisplayed() {
ViewElement testView = new AbstractViewElement(mock(Locator.class)) {
@Require
private Element displayed = new AlwaysDisplayedLabel();
@Require
private Element notDisplayed = new NeverDisplayedElement();
};
assertFalse("isDisplayed should return false if not all required elements are displayed.",
testView.isDisplayed());
}
@Test
public void shouldReturnTrueIfRequireAllIsUsedAndAllElementsAreDisplayed() {
@RequireAll
class TestViewElement extends AbstractViewElement {
private Element displayed = new AlwaysDisplayedLabel();
private Element displayed2 = new AlwaysDisplayedLabel();
TestViewElement(Locator parent) {
super(parent);
}
}
ViewElement testView = new TestViewElement(mock(Locator.class));
assertTrue("isDisplayed should return true if all required elements are displayed and "
+ "RequireAll annotation is used.", testView.isDisplayed());
}
@Test
public void shouldReturnFalseIfRequireAllIsUsedAndNotAllElementsAreDisplayed() {
@RequireAll class TestViewElement extends AbstractViewElement {
private Element displayed = new AlwaysDisplayedLabel();
private Element notDisplayed = new NeverDisplayedElement();
TestViewElement(Locator parent) {
super(parent);
}
}
ViewElement testView = new TestViewElement(mock(Locator.class));
assertFalse("isDisplayed should return false if not all required elements are displayed " +
"and RequireAll annotation is used.", testView.isDisplayed());
}
@Test
public void shouldReturnTrueIfOnlyElementNotDisplayedIsNotRequired() {
@RequireAll class TestViewElement extends AbstractViewElement {
private Element displayed = new AlwaysDisplayedLabel();
@NotRequired
private Element notDisplayed = new NeverDisplayedElement();
TestViewElement(Locator parent) {
super(parent);
}
}
ViewElement testView = new TestViewElement(mock(Locator.class));
assertTrue("isDisplayed should return true if only element not displayed is not required " +
"when RequireAll annotation is used.", testView.isDisplayed());
}
@Test
public void shouldReturnFalseIfOnlyElementDisplayedIsNotRequired() {
@RequireAll class TestViewElement extends AbstractViewElement {
@NotRequired
private Element displayed = new AlwaysDisplayedLabel();
private Element notDisplayed = new NeverDisplayedElement();
TestViewElement(Locator parent) {
super(parent);
}
}
ViewElement testView = new TestViewElement(mock(Locator.class));
assertFalse("isDisplayed should return false if only element actually displayed is not " +
"required when RequireAll annotation is used.", testView.isDisplayed());
}
@Test
public void shouldAllowBeingOverridden() {
ViewElement testView = new AbstractViewElement(mock(Locator.class)) {
@Require
private Element displayed = new AlwaysDisplayedLabel();
@Override
public boolean isDisplayed() {
return super.isDisplayed();
}
};
assertTrue(testView.isDisplayed());
}
@Test(expected = TestException.class)
public void shouldPropagateUncheckedExceptions() {
Element throwsExceptionOnIsDisplayed = mock(Element.class);
when(throwsExceptionOnIsDisplayed.isDisplayed()).thenThrow(TestException.class);
ViewElement testView = new AbstractViewElement(mock(Locator.class)) {
@Require Element element = throwsExceptionOnIsDisplayed;
};
testView.isDisplayed();
}
@Test
public void shouldReturnTrueIfRequiredViewIsDisplayedButNotLoaded() {
ViewElement mockElement = mock(ViewElement.class);
when(mockElement.isDisplayed()).thenReturn(true);
when(mockElement.isLoaded()).thenReturn(false);
ViewElement testView = new AbstractViewElement(mock(Locator.class)) {
@Require
ViewElement element = mockElement;
};
assertTrue("Expected ViewElement to be displayed due to single required field that is a " +
"displayed view.", testView.isDisplayed());
}
// This scenario doesn't make any sense, but serves to prove we're not looking at isLoaded for
// isDisplayed.
@Test
public void shouldReturnFalseIfRequiredViewIsNotDisplayedButIsLoadedAndPresent() {
ViewElement mockElement = mock(ViewElement.class);
when(mockElement.isDisplayed()).thenReturn(false);
when(mockElement.isLoaded()).thenReturn(true);
when(mockElement.isPresent()).thenReturn(true);
ViewElement testView = new AbstractViewElement(mock(Locator.class)) {
@Require
ViewElement element = mockElement;
};
assertFalse("Expected ViewElement to not be displayed due to single required field that " +
"is a not displayed view.", testView.isDisplayed());
}
@Test(expected = NoRequiredElementsException.class)
public void shouldIgnoreFieldsAnnotatedWithContext() {
@RequireAll class TestViewElement extends AbstractViewElement {
@Context
Element element = mock(Element.class);
public TestViewElement() {
super(mock(Locator.class));
}
};
TestViewElement testView = new TestViewElement();
testView.isDisplayed();
}
@Test(expected = NoRequiredElementsException.class)
public void shouldNotConsiderIrrelevantFieldsAsAbleToBeRequired() {
@RequireAll class TestViewElement extends AbstractViewElement {
String aString;
public TestViewElement() {
super(mock(Locator.class));
}
};
TestViewElement testView = new TestViewElement();
testView.isDisplayed();
}
@Test(expected = NoRequiredElementsException.class)
public void shouldReconsiderEmptyConditionsListIfNoRequiredFieldIsDisplayable() {
@RequireAll class TestViewElement extends AbstractViewElement {
Findable findable;
public TestViewElement() {
super(mock(Locator.class));
}
};
TestViewElement testView = new TestViewElement();
testView.isDisplayed();
}
@Test
public void shouldReturnTrueIfRequireIsSpecifiedForAListWithASingleElementLoaded() {
class TestViewElement extends AbstractViewElement {
@Require
private List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
elements.add(new AlwaysDisplayedLabel());
}
}
TestViewElement view = new TestViewElement();
assertTrue("isDisplayed should return true if no specific requirement limit is specified for" +
" for a list that has at least a single element displayed.", view.isDisplayed());
}
@Test
public void shouldReturnFalseIfRequireIsSpecifiedForAListWithNoElementsLoaded() {
class TestViewElement extends AbstractViewElement {
@Require
private List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
}
}
TestViewElement view = new TestViewElement();
assertFalse("isDisplayed should return false if a list with no elements displayed is specified" +
" required with no requirement limit.", view.isDisplayed());
}
@Test
public void shouldReturnTrueIfExactNumberOfRequiredElementsAreDisplayed() {
class TestViewElement extends AbstractViewElement {
@Require(exactly = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 5) {
elements.add(new AlwaysDisplayedLabel());
}
}
}
TestViewElement element = new TestViewElement();
assertTrue("isDisplayed should return true if a list with exactly as many elements as specified" +
" are displayed.", element.isDisplayed());
}
@Test
public void shouldReturnFalseIfExactNumberOfRequiredElementsAreNotDisplayed() {
class TestViewElement extends AbstractViewElement {
@Require(exactly = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 4) {
elements.add(new AlwaysDisplayedLabel());
}
elements.add(new NeverDisplayedElement());
}
}
TestViewElement element = new TestViewElement();
assertFalse("isDisplayed should return false if a list with less than exactly as many elements as specified" +
" are displayed.", element.isDisplayed());
}
@Test
public void shouldReturnTrueIfAtLeastAsManyRequiredElementsAreDisplayed() {
class TestViewElement extends AbstractViewElement {
@Require(atLeast = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 5) {
elements.add(new AlwaysDisplayedLabel());
}
}
}
TestViewElement element = new TestViewElement();
assertTrue("isDisplayed should return true if at least a number of elements are displayed as" +
" specified to be required.", element.isDisplayed());
}
@Test
public void shouldReturnTrueIfAtLeastAsManyRequiredElementsAreDisplayedWithUndisplayedElements() {
class TestViewElement extends AbstractViewElement {
@Require(atLeast = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 5) {
elements.add(new AlwaysDisplayedLabel());
}
while (elements.size() < 10) {
elements.add(new NeverDisplayedElement());
}
}
}
TestViewElement element = new TestViewElement();
assertTrue("isDisplayed should return true if at least a number of elements are displayed as" +
" specified to be required, with any number of non-displayed elements.", element.isDisplayed());
}
@Test
public void shouldReturnFalseIfLessThanTheMinimumRequiredElementsAreDisplayed() {
class TestViewElement extends AbstractViewElement {
@Require(atLeast = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 4) {
elements.add(new AlwaysDisplayedLabel());
}
while (elements.size() < 10) {
elements.add(new NeverDisplayedElement());
}
}
}
TestViewElement element = new TestViewElement();
assertFalse("isDisplayed should return false if a number of elements less than specified " +
" as required are displayed.", element.isDisplayed());
}
@Test
public void shouldReturnTrueIfAtMostAsManyRequiredElementsAreDisplayed() {
class TestViewElement extends AbstractViewElement {
@Require(atMost = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 5) {
elements.add(new AlwaysDisplayedLabel());
}
}
}
TestViewElement element = new TestViewElement();
assertTrue("isDisplayed should return true if at most a number of elements are displayed as" +
" specified to be required.", element.isDisplayed());
}
@Test
public void shouldReturnTrueIfAtMostAsManyRequiredElementsAreDisplayedWithUndisplayedElements() {
class TestViewElement extends AbstractViewElement {
@Require(atMost = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 4) {
elements.add(new AlwaysDisplayedLabel());
}
while (elements.size() < 10) {
elements.add(new NeverDisplayedElement());
}
}
}
TestViewElement element = new TestViewElement();
assertTrue("isDisplayed should return true if at least a number of elements are displayed as" +
" specified to be required, with any number of non-displayed elements.", element.isDisplayed());
}
@Test
public void shouldReturnFalseIfMoreThanTheMaximumRequiredElementsAreDisplayed() {
class TestViewElement extends AbstractViewElement {
@Require(atMost = 5)
List<Element> elements;
public TestViewElement() {
super(mock(Locator.class));
elements = new ArrayList<Element>();
while (elements.size() < 6) {
elements.add(new AlwaysDisplayedLabel());
}
while (elements.size() < 10) {
elements.add(new NeverDisplayedElement());
}
}
}
TestViewElement element = new TestViewElement();
assertFalse("isDisplayed should return false if a number of elements less than specified " +
" as required are displayed.", element.isDisplayed());
}
class TestException extends RuntimeException {}
}