package WEBPIECESxPACKAGE; import java.awt.AWTException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Assert; import org.junit.Before; //import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver.Options; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.interactions.Actions; import org.webpieces.ddl.api.JdbcApi; import org.webpieces.ddl.api.JdbcConstants; import org.webpieces.ddl.api.JdbcFactory; import org.webpieces.plugins.hibernate.HibernatePlugin; import org.webpieces.webserver.test.Asserts; import org.webpieces.webserver.test.SeleniumOverridesForTest; import com.google.inject.Binder; import com.google.inject.Module; /** * If you install firefox 47.0.1, these tests will just work out of the box * Until then, we mark this test as ignored for you * * @author dhiller */ //@Ignore public class TestLesson4WithSelenium { private static WebDriver driver; private JdbcApi jdbc = JdbcFactory.create(JdbcConstants.jdbcUrl, JdbcConstants.jdbcUser, JdbcConstants.jdbcPassword); private static String pUnit = HibernatePlugin.PERSISTENCE_TEST_UNIT; //see below comments in AppOverrideModule //private MockRemoteSystem mockRemote = new MockRemoteSystem(); //or your favorite mock library private int httpPort; private int httpsPort; @Before public void setUp() throws InterruptedException, ClassNotFoundException { driver = new FirefoxDriver(); Asserts.assertWasCompiledWithParamNames("test"); jdbc.dropAllTablesFromDatabase(); //you may want to create this server ONCE in a static method BUT if you do, also remember to clear out all your //mocks after every test and NOT drop tables but clear and re-populate Server webserver = new Server( new SeleniumOverridesForTest(), new AppOverridesModule(), new ServerConfig(0, 0, pUnit)); webserver.start(); httpPort = webserver.getUnderlyingHttpChannel().getLocalAddress().getPort(); httpsPort = webserver.getUnderlyingHttpsChannel().getLocalAddress().getPort(); } @After public void tearDown() { Options manage = driver.manage(); manage.deleteAllCookies(); driver.close(); driver.quit(); } @Test public void testRedirectToOriginallyRequestedUrlAfterLogin() throws ClassNotFoundException { driver.navigate().to("https://localhost:"+httpsPort+"/secure/crud/user/list"); Assert.assertEquals("https://localhost:"+httpsPort+"/login", driver.getCurrentUrl()); driver.findElement(By.id("user")).sendKeys("bob"); driver.findElement(By.id("submit")).click(); String text = driver.findElement(By.id("errorDiv")).getText(); Assert.assertTrue(text.contains("No Soup for you!")); String errorMsg = driver.findElement(By.id("username_errorMsg")).getText(); Assert.assertTrue(errorMsg.contains("I lied, Username must be 'dean'")); WebElement userInput = driver.findElement(By.id("user")); userInput.clear(); userInput.sendKeys("dean"); driver.findElement(By.id("submit")).click(); //ensure it redirects back to originally requested url... Assert.assertEquals("https://localhost:"+httpsPort+"/secure/crud/user/list", driver.getCurrentUrl()); } @Test public void testAjaxRedirect() throws ClassNotFoundException { driver.navigate().to("https://localhost:"+httpsPort+"/secure/ajax/user/list"); Assert.assertEquals("https://localhost:"+httpsPort+"/login", driver.getCurrentUrl()); driver.findElement(By.id("user")).sendKeys("dean"); driver.findElement(By.id("submit")).click(); Assert.assertEquals("https://localhost:"+httpsPort+"/secure/ajax/user/list", driver.getCurrentUrl()); //open new tab and logout openNewTabAndLogoutAndComeBackToThisTab(); driver.findElement(By.id("editLink_2")).click(); //redirected to login page with ajax redirect Assert.assertEquals("https://localhost:"+httpsPort+"/login", driver.getCurrentUrl()); } @Test public void testBasicLogin() throws ClassNotFoundException { driver.navigate().to("https://localhost:"+httpsPort+"/login"); driver.findElement(By.id("user")).sendKeys("dean"); driver.findElement(By.id("submit")).click(); //ensure we redirect to logged in base home page Assert.assertEquals("https://localhost:"+httpsPort+"/secure/loggedinhome", driver.getCurrentUrl()); //now if we navigate to login page, it automatically redirects us to the loggidinhome page since we are already logged in driver.navigate().to("https://localhost:"+httpsPort+"/login"); Assert.assertEquals("https://localhost:"+httpsPort+"/secure/loggedinhome", driver.getCurrentUrl()); } /** * VERY VERY IMPORTANT SECURITY TEST testing that back button cannot go back and see logged in pages when logged * out. This makes sure we tell browser pages are cached. This should be extended to more browsers as browsers in * the past have varied in their behavior here */ @Test public void testBackButtonToSecurePageWhenLoggedOut() throws ClassNotFoundException, AWTException { driver.navigate().to("https://localhost:"+httpsPort+"/login"); driver.findElement(By.id("user")).sendKeys("dean"); driver.findElement(By.id("submit")).click(); //ensure we redirect to logged in base home page Assert.assertEquals("https://localhost:"+httpsPort+"/secure/loggedinhome", driver.getCurrentUrl()); driver.navigate().to("https://localhost:"+httpsPort+"/secure/crud/user/list"); openNewTabAndLogoutAndComeBackToThisTab(); driver.navigate().back(); //back button Assert.assertEquals("https://localhost:"+httpsPort+"/login", driver.getCurrentUrl()); } private void openNewTabAndLogoutAndComeBackToThisTab() { WebElement link = driver.findElement(By.id("loggedinhome")); new Actions(driver) .keyDown(Keys.CONTROL) .keyDown(Keys.SHIFT) .click(link) .keyUp(Keys.SHIFT) .keyUp(Keys.CONTROL) .perform(); //open new tab driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t"); List<String> tabs = new ArrayList<String> (driver.getWindowHandles()); driver.switchTo().window(tabs.get(1)); driver.navigate().to("https://localhost:"+httpsPort+"/secure/loggedinhome"); driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS); driver.findElement(By.id("logout")).click(); driver.switchTo().window(tabs.get(0)); driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS); } @Test public void testChunking() throws ClassNotFoundException { //We know this web page is big enough to test our chunking compatibility with a real browser driver.get("http://localhost:"+httpPort+""); String pageSource = driver.getPageSource(); Assert.assertTrue("pageSource="+pageSource, pageSource.contains("Webpieces Webserver is the most")); } private class AppOverridesModule implements Module { @Override public void configure(Binder binder) { //Add overrides here generally using mocks from fields in the test class //ie. //binder.bind(SomeRemoteSystem.class).toInstance(mockRemote); //see above comment on the field mockRemote } } }