package net.thucydides.core.pages.integration; import net.thucydides.core.pages.PageObject; import net.thucydides.core.pages.WebElementFacade; import net.thucydides.core.pages.WebElementFacadeImpl; import net.thucydides.core.util.MockEnvironmentVariables; import net.thucydides.core.webdriver.Configuration; import net.thucydides.core.webdriver.SystemPropertiesConfiguration; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.openqa.selenium.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; public class WhenManagingAPageObject { @Mock WebDriver driver; @Mock WebElement mockButton; MockEnvironmentVariables environmentVariables; Configuration configuration; @Before public void initMocks() { MockitoAnnotations.initMocks(this); environmentVariables = new MockEnvironmentVariables(); configuration = new SystemPropertiesConfiguration(environmentVariables); } class BasicPageObject extends PageObject { protected WebElement button; public BasicPageObject(WebDriver driver) { super(driver); } protected WebElement getButton() { return mockButton; } public void invokeWaitABit(long time) { waitABit(500); } } @Test public void the_page_gets_the_title_from_the_web_page() { when(driver.getTitle()).thenReturn("Google Search Page"); BasicPageObject page = new BasicPageObject(driver); assertThat(page.getTitle(), is("Google Search Page")); } @Test public void page_will_wait_for_rendered_element_if_it_is_already_present() { WebElement renderedElement = mock(WebElement.class); List<WebElement> renderedElements = new ArrayList<WebElement>(); renderedElements.add(renderedElement); when(driver.findElement(any(By.class))).thenReturn(renderedElement); when(driver.findElements(any(By.class))).thenReturn(renderedElements); when(renderedElement.isDisplayed()).thenReturn(true); BasicPageObject page = new BasicPageObject(driver); page.waitForRenderedElements(By.id("whatever")); } @Test public void thenReturnElementList_will_return_the_list_of_matching_elements() { WebElement renderedElement = mock(WebElement.class); List<WebElement> renderedElements = new ArrayList<WebElement>(); renderedElements.add(renderedElement); when(driver.findElement(any(By.class))).thenReturn(renderedElement); when(driver.findElements(any(By.class))).thenReturn(renderedElements); BasicPageObject page = new BasicPageObject(driver); List<WebElement> elementList = page.thenReturnElementList(By.className("whatever")); assertThat(elementList, is(renderedElements)); } @Test public void page_will_wait_for_rendered_element_to_disappear() { List<WebElement> emptyList = Arrays.asList(); when(driver.findElements(any(By.class))).thenReturn(emptyList); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(100); page.waitForRenderedElementsToDisappear(By.id("whatever")); } @Test public void page_will_wait_for_rendered_element_to_disappear_using_shortened_form() { List<WebElement> emptyList = Arrays.asList(); when(driver.findElements(any(By.class))).thenReturn(emptyList); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(100); page.waitForAbsenceOf("#whatever"); } @Test public void page_can_delay_requests_for_a_short_period() { long start = System.currentTimeMillis(); BasicPageObject page = new BasicPageObject(driver); page.invokeWaitABit(500); assertThat((int) (System.currentTimeMillis() - start), greaterThanOrEqualTo(500)); } @Test(expected = TimeoutException.class) public void wait_for_rendered_element_to_disappear_will_fail_if_element_does_not_disappear() { WebElement textBlock = mock(WebElement.class); when(textBlock.isDisplayed()).thenReturn(true); List<WebElement> listWithElements = Arrays.asList(textBlock); when(driver.findElements(any(By.class))).thenReturn(listWithElements); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(150); page.waitForRenderedElementsToDisappear(By.id("whatever")); } @Test public void page_will_wait_for_rendered_element_if_it_is_not_already_present() { WebElement renderedElement = mock(WebElement.class); List<WebElement> renderedElements = new ArrayList<WebElement>(); renderedElements.add(renderedElement); when(driver.findElement(any(By.class))).thenReturn(renderedElement); when(driver.findElements(any(By.class))).thenReturn(renderedElements); when(renderedElement.isDisplayed()).thenReturn(false).thenReturn(false).thenReturn(true); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(200); page.waitForRenderedElements(By.id("whatever")); } @Test public void page_will_wait_for_title_to_appear_if_requested() { BasicPageObject page = new BasicPageObject(driver); when(driver.getTitle()).thenReturn("waiting..").thenReturn("a title"); page.waitForTitleToAppear("a title"); } @Test public void page_will_wait_for_title_to_appear_if_already_there() { BasicPageObject page = new BasicPageObject(driver); when(driver.getTitle()).thenReturn("a title"); page.waitForTitleToAppear("a title"); } @Test public void page_will_wait_for_title_to_disappear_if_requested() { BasicPageObject page = new BasicPageObject(driver); when(driver.getTitle()).thenReturn("a title").thenReturn("all gone"); page.waitForTitleToDisappear("a title"); } @Test(expected = TimeoutException.class) public void page_will_wait_for_title_to_disappear_should_fail_if_title_doesnt_disappear() { BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(100); when(driver.getTitle()).thenReturn("a title"); page.waitForTitleToDisappear("a title"); } @Test public void page_will_wait_for_text_to_appear_in_element_if_requested() { BasicPageObject page = new BasicPageObject(driver); WebElement textBlock = mock(WebElement.class); WebElement searchedBlock = mock(WebElement.class); List<WebElement> emptyList = Arrays.asList(); List<WebElement> listWithElements = Arrays.asList(textBlock); when(searchedBlock.findElements(any(By.class))).thenReturn(emptyList).thenReturn(listWithElements); when(searchedBlock.getText()).thenReturn("contains 'hi there'"); page.waitForTextToAppear(searchedBlock,"hi there"); } @Test public void wait_for_text_to_appear_in_element_will_succeed_if_element_is_already_present() { BasicPageObject page = new BasicPageObject(driver); WebElement textBlock = mock(WebElement.class); WebElement searchedBlock = mock(WebElement.class); List<WebElement> emptyList = Arrays.asList(); List<WebElement> listWithElements = Arrays.asList(textBlock); when(searchedBlock.findElements(any(By.class))).thenReturn(listWithElements); when(searchedBlock.getText()).thenReturn("contains 'hi there'"); page.waitForTextToAppear(searchedBlock,"hi there"); } @Test(expected = TimeoutException.class) public void wait_for_text_to_appear_in_element_will_fail_if_text_does_not_appear() { BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(150); WebElement searchedBlock = mock(WebElement.class); List<WebElement> emptyList = Arrays.asList(); when(searchedBlock.findElements(any(By.class))).thenReturn(emptyList); when(searchedBlock.getText()).thenReturn("no matching text here"); page.waitForTextToAppear(searchedBlock,"hi there"); } @Test public void page_will_wait_for_text_to_appear_successfully_if_already_present() { BasicPageObject page = new BasicPageObject(driver); WebElement textBlock = mock(WebElement.class); WebElement searchedBlock = mock(WebElement.class); List<WebElement> listWithElements = Arrays.asList(textBlock); when(searchedBlock.findElements(any(By.class))).thenReturn(listWithElements); when(searchedBlock.getText()).thenReturn("contains 'hi there'"); page.waitForTextToAppear(searchedBlock,"hi there"); } @Test public void page_will_wait_for_text_to_appear_in_an_element_if_requested() { BasicPageObject page = new BasicPageObject(driver); WebElement textBlock = mock(WebElement.class); WebElement searchedBlock = mock(WebElement.class); List<WebElement> emptyList = Arrays.asList(); List<WebElement> listWithElements = Arrays.asList(textBlock); when(searchedBlock.findElements(any(By.class))).thenReturn(emptyList).thenReturn(listWithElements); when(searchedBlock.getText()).thenReturn("contains 'hi there'"); page.waitForAnyTextToAppear(searchedBlock, "hi there"); } @Test(expected=TimeoutException.class) public void page_will_fail_if_single_text_fails_to_appear_in_an_element_if_requested() { BasicPageObject page = new BasicPageObject(driver); WebElement searchedBlock = mock(WebElement.class); List<WebElement> emptyList = Arrays.asList(); when(searchedBlock.findElements(any(By.class))).thenReturn(emptyList); when(searchedBlock.getText()).thenReturn("no matching text"); page.setWaitForTimeout(200); page.waitForAnyTextToAppear(searchedBlock, "hi there"); } @Test(expected=TimeoutException.class) public void page_will_fail_if_text_fails_to_appear_in_an_element_if_requested() { BasicPageObject page = new BasicPageObject(driver); WebElement searchedBlock = mock(WebElement.class); List<WebElement> emptyList = Arrays.asList(); when(searchedBlock.findElements(any(By.class))).thenReturn(emptyList); when(searchedBlock.getText()).thenReturn("no matching text"); page.setWaitForTimeout(200); page.waitForAnyTextToAppear(searchedBlock, "hi there"); } @Test public void entering_a_value_in_a_field_will_clear_it_first() { WebElement field = mock(WebElement.class); BasicPageObject page = new BasicPageObject(driver); when(field.isEnabled()).thenReturn(true); when(field.getTagName()).thenReturn("input"); page.typeInto(field, "some value"); verify(field).clear(); verify(field).sendKeys("some value"); } @Test public void should_provide_a_fluent_api_for_entering_a_value_in_a_field_using_webelement() { WebElement field = mock(WebElement.class); BasicPageObject page = new BasicPageObject(driver); when(field.isEnabled()).thenReturn(true); when(field.getTagName()).thenReturn("input"); page.enter("some value").into(field); verify(field).clear(); verify(field).sendKeys("some value"); } @Test public void should_provide_a_fluent_api_for_entering_a_value_in_a_field_using_webelementfacade() { WebElement field = mock(WebElement.class); WebElementFacade facade = WebElementFacadeImpl.wrapWebElement(driver, field, 0L); BasicPageObject page = new BasicPageObject(driver); when(field.isEnabled()).thenReturn(true); when(field.getTagName()).thenReturn("input"); page.enter("some value").into(facade); verify(field).clear(); verify(field).sendKeys("some value"); } @Test public void should_provide_a_fluent_api_for_entering_a_value_in_a_field_using_a_selector() { WebElement field = mock(WebElement.class); when(driver.findElement(By.id("field-id"))).thenReturn(field); when(field.isEnabled()).thenReturn(true); when(field.getTagName()).thenReturn("input"); BasicPageObject page = new BasicPageObject(driver); page.enter("some value").intoField(By.id("field-id")); verify(field).clear(); verify(field).sendKeys("some value"); } @Test(expected=TimeoutException.class) public void page_will_throw_exception_if_waiting_for_rendered_element_does_not_exist() { when(driver.findElement(any(By.class))).thenThrow(new NoSuchElementException("No such element")); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(200); page.waitForRenderedElements(By.id("whatever")); } @Test(expected=TimeoutException.class) public void page_will_throw_exception_if_waiting_for_rendered_element_is_not_visible() { WebElement renderedElement = mock(WebElement.class); when(driver.findElement(any(By.class))).thenReturn(renderedElement); when(renderedElement.isDisplayed()).thenReturn(false); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(200); page.waitForRenderedElements(By.id("whatever")); } @Test public void page_will_succeed_for_any_of_several_rendered_elements() { WebElement renderedElement = mock(WebElement.class); elementIsRendered(renderedElement, By.id("element1")); noElementIsRendered(By.id("element2")); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(200); page.waitForAnyRenderedElementOf(By.id("element1"), By.id("element2")); } @Test(expected=TimeoutException.class) public void page_will_fail_for_any_of_several_rendered_elements_if_element_is_displayed_but_not_rendered() { WebElement renderedElement = mock(WebElement.class); elementIsDisplayedButNotRendered(renderedElement, By.id("element1")); noElementIsRendered(By.id("element2")); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(200); page.waitForAnyRenderedElementOf(By.id("element1"), By.id("element2")); } @Test public void page_will_wait_for_any_of_several_rendered_elements() { WebElement renderedElement = mock(WebElement.class); elementIsRenderedWithDelay(renderedElement, By.id("element1")); noElementIsRendered(By.id("element2")); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(1000); page.waitForAnyRenderedElementOf(By.id("element1"), By.id("element2")); } @Test(expected = TimeoutException.class) public void page_will_fail_if_none_of_the_several_rendered_elements_are_present() { noElementIsRendered(By.id("element1")); noElementIsRendered(By.id("element2")); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(1000); page.waitForAnyRenderedElementOf(By.id("element1"), By.id("element2")); } @Test public void page_can_wait_for_an_element_to_disappear() { WebElement renderedElement = mock(WebElement.class); elementDisappearsAfterADelay(renderedElement, By.id("element1")); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(200); page.waitForRenderedElementsToDisappear(By.id("element1")); } @Test public void page_can_wait_for_an_element_to_disappear_if_element_is_not_initially_displayed() { noElementIsRendered(By.id("element1")); BasicPageObject page = new BasicPageObject(driver); page.setWaitForTimeout(200); page.waitForRenderedElementsToDisappear(By.id("element1")); } private void noElementIsRendered(By criteria) { List<WebElement> emptyList = Arrays.asList(); when(driver.findElement(criteria)).thenThrow(new NoSuchElementException("No such element")); when(driver.findElements(criteria)).thenReturn(emptyList); } private void elementIsRendered(WebElement renderedElement, By criteria) { when(renderedElement.isDisplayed()).thenReturn(true); List<WebElement> listWithRenderedElement = Arrays.asList((WebElement) renderedElement); when(driver.findElement(criteria)).thenReturn(renderedElement); when(driver.findElements(criteria)).thenReturn(listWithRenderedElement); } private void elementIsDisplayedButNotRendered(WebElement renderedElement, By criteria) { when(renderedElement.isDisplayed()).thenReturn(false); List<WebElement> listWithRenderedElement = Arrays.asList((WebElement) renderedElement); when(driver.findElement(criteria)).thenReturn(renderedElement); when(driver.findElements(criteria)).thenReturn(listWithRenderedElement); } private void elementIsRenderedWithDelay(WebElement renderedElement, By criteria) { List<WebElement> emptyList = Arrays.asList(); when(renderedElement.isDisplayed()).thenReturn(false).thenReturn(true); List<WebElement> listWithRenderedElement = Arrays.asList((WebElement) renderedElement); when(driver.findElement(criteria)).thenThrow(new NoSuchElementException("No such element")) .thenThrow(new NoSuchElementException("No such element")) .thenReturn(renderedElement); when(driver.findElements(criteria)).thenReturn(emptyList) .thenReturn(listWithRenderedElement); } private void elementDisappearsAfterADelay(WebElement renderedElement, By criteria) { List<WebElement> emptyList = Arrays.asList(); when(renderedElement.isDisplayed()).thenReturn(true).thenReturn(false); List<WebElement> listWithRenderedElement = Arrays.asList((WebElement) renderedElement); when(driver.findElement(criteria)).thenReturn(renderedElement) .thenReturn(renderedElement) .thenThrow(new NoSuchElementException("No such element")); when(driver.findElements(criteria)).thenReturn(listWithRenderedElement) .thenReturn(listWithRenderedElement) .thenReturn(emptyList); } @Test(expected=AssertionError.class) public void should_be_visible_should_throw_an_assertion_if_element_is_not_visible() { BasicPageObject page = new BasicPageObject(driver); WebElement field = mock(WebElement.class); when(field.isDisplayed()).thenReturn(false); page.shouldBeVisible(field); } @Test(expected=AssertionError.class) public void should_be_not_visible_should_throw_an_assertion_if_element_is_visible() { BasicPageObject page = new BasicPageObject(driver); WebElement field = mock(WebElement.class); when(field.isDisplayed()).thenReturn(true); page.shouldNotBeVisible(field); } @Test public void should_be_not_visible_should_do_nothing_if_element_is_not_visible() { BasicPageObject page = new BasicPageObject(driver); WebElement field = mock(WebElement.class); when(field.isDisplayed()).thenReturn(false); page.shouldNotBeVisible(field); } @Test public void should_be_visible_should_do_nothing_if_element_is_visible() { BasicPageObject page = new BasicPageObject(driver); WebElement field = mock(WebElement.class); when(field.isDisplayed()).thenReturn(true); page.shouldBeVisible(field); } @Test public void should_be_visible_should_handle_changing_field_state() { BasicPageObject page = new BasicPageObject(driver); WebElement field = mock(WebElement.class); when(field.isDisplayed()).thenReturn(true); page.shouldBeVisible(field); when(field.isDisplayed()).thenReturn(false); page.shouldNotBeVisible(field); } @Test(expected = WebDriverException.class) public void when_clicking_on_something_should_throw_exception_if_it_fails_twice() { BasicPageObject page = new BasicPageObject(driver); when(mockButton.isEnabled()).thenReturn(true); when(mockButton.getTagName()).thenReturn("button"); doThrow(new WebDriverException()).when(mockButton).click(); page.clickOn(page.getButton()); } @Test public void page_should_detect_if_a_web_element_contains_a_string() { BasicPageObject page = new BasicPageObject(driver); WebElement searchedBlock = mock(WebElement.class); when(searchedBlock.getText()).thenReturn("red green blue"); assertThat(page.containsTextInElement(searchedBlock, "red"), is(true)); } @Test public void page_should_detect_if_a_web_element_does_not_contain_a_string() { BasicPageObject page = new BasicPageObject(driver); WebElement searchedBlock = mock(WebElement.class); when(searchedBlock.getText()).thenReturn("red green blue"); assertThat(page.containsTextInElement(searchedBlock, "orange"), is(false)); } @Test(expected=AssertionError.class) public void should_contain_text_in_element_should_throw_an_assertion_if_text_is_not_visible() { BasicPageObject page = new BasicPageObject(driver); WebElement searchedBlock = mock(WebElement.class); when(searchedBlock.getText()).thenReturn("red green blue"); page.shouldContainTextInElement(searchedBlock, "orange"); } @Test public void should_contain_text_in_web_element_should_do_nothing_if_text_is_present() { BasicPageObject page = new BasicPageObject(driver); WebElement searchedBlock = mock(WebElement.class); when(searchedBlock.getText()).thenReturn("red green blue"); page.shouldContainTextInElement(searchedBlock, "red"); } @Test public void should_not_contain_text_in_web_element_should_do_nothing_if_text_is_not_present() { BasicPageObject page = new BasicPageObject(driver); WebElement searchedBlock = mock(WebElement.class); when(searchedBlock.getText()).thenReturn("red green blue"); page.shouldNotContainTextInElement(searchedBlock, "orange"); } }