diff --git a/core/src/main/scala/org/scalawebtest/core/Specs.scala b/core/src/main/scala/org/scalawebtest/core/Specs.scala index 520e010..95516a7 100755 --- a/core/src/main/scala/org/scalawebtest/core/Specs.scala +++ b/core/src/main/scala/org/scalawebtest/core/Specs.scala @@ -19,7 +19,7 @@ import java.util.logging.Level import org.openqa.selenium.Cookie import org.scalatest._ import org.scalatest.concurrent.Eventually -import org.scalatest.selenium.WebBrowser +import org.scalatest.selenium.{Page, WebBrowser} import org.slf4j.LoggerFactory import scala.collection.mutable.ListBuffer @@ -29,7 +29,22 @@ abstract class FlatSpecBehavior extends FlatSpec with Matchers with Inspectors abstract class FreeSpecBehavior extends FreeSpec with Matchers with Inspectors -abstract class IntegrationFlatSpec extends FlatSpecBehavior with IntegrationSpec +abstract class IntegrationFlatSpec extends FlatSpecBehavior with IntegrationSpec { + /** + * As the IntegrationSpec will "go to" the defined url, as part of [[BeforeAndAfterEach.beforeEach()]], changing the path + * within the test is too late. To change the path for a test and all its successors, you can use afterChangingPathTo in between tests, + * providing the new path as parameter. + */ + def afterChangingPathTo(newPath: String): Unit = { + val timesChanged = pathChangeCounter.getOrElse(path, 0) + //calculate a postfix to make the test name unique + val postfix = "_" * timesChanged + registerTest("change path to " + newPath + " " + postfix)(path = newPath) + pathChangeCounter += newPath -> (timesChanged + 1) + } + + var pathChangeCounter: Map[String, Int] = Map() +} abstract class IntegrationFreeSpec extends FreeSpecBehavior with IntegrationSpec @@ -56,6 +71,18 @@ trait IntegrationSpec extends WebBrowser with Suite with BeforeAndAfterEach with */ val config = new Configuration + /** + * Stores the path with prefixed [[IntegrationSettings.host]] and [[IntegrationSpec.projectRoot]] as url. + * Before each test [[WebBrowser.goTo()]] with the currently stored url will be executed, but only + * if [[WebClientExposingDriver.getCurrentUrl]] doesn't equal url. + */ + def path_=(path: String): Unit = { + url = s"$host$projectRoot$path" + } + + def path = url.replaceFirst(host, "").replaceFirst(projectRoot, "") + + private var url: String = "" /** * Override to encode your project specific login mechanism. @@ -94,7 +121,7 @@ trait IntegrationSpec extends WebBrowser with Suite with BeforeAndAfterEach with java.util.logging.Logger.getLogger("net.lightbody").setLevel(Level.OFF) } - override def afterEach() { + override def afterEach(): Unit = { cookiesToBeDiscarded.foreach(cookie => delete cookie cookie.getName) cookiesToBeDiscarded.clear() } @@ -102,7 +129,7 @@ trait IntegrationSpec extends WebBrowser with Suite with BeforeAndAfterEach with /** * Overwrite beforeLogin() and afterLogin() for test-specific tasks */ - override def beforeAll() { + override def beforeAll(): Unit = { beforeLogin() avoidLogSpam() applyConfiguration(config) @@ -111,6 +138,10 @@ trait IntegrationSpec extends WebBrowser with Suite with BeforeAndAfterEach with afterLogin() } + override def beforeEach(): Unit = { + navigateToUrl(url) + } + /** * Sets a cookie for the current test. Any cookie set through this method * is discarded after a test. @@ -118,7 +149,7 @@ trait IntegrationSpec extends WebBrowser with Suite with BeforeAndAfterEach with def setCookieForSingleTest(name: String, value: String) { val cookie: Cookie = new Cookie(name, value) webDriver.manage().addCookie(cookie) - add cookie (name, value) + add cookie(name, value) cookiesToBeDiscarded += cookie } @@ -131,11 +162,25 @@ trait IntegrationSpec extends WebBrowser with Suite with BeforeAndAfterEach with afterLogin() } - def navigateTo(path: String) { - val targetUrl: String = s"$host$path" + /** + * To navigate to a path during. For most case calling the setter on path is a better solution. + * Only use this function, if you have to change the path during a test. + * For all other cases use "path = \"/xyz\"" or afterChangingPathTo("xyz") + * + * Please be aware that having to change the path during a test is usually a sign, that your test + * tests multiple things. Try to focus on one thing per test. + */ + def navigateTo(path: String): Unit = { + navigateToUrl(s"$host$projectRoot$path") + } + + private def navigateToUrl(targetUrl: String): Unit = { if (pageSource == null || !(targetUrl equals webDriver.getCurrentUrl)) { logger.info("Going to " + targetUrl) go to targetUrl + } else { + logger.info("Remaining at " + targetUrl + " without refreshing page") } } + } \ No newline at end of file diff --git a/integration_test/src/it/scala/org/scalawebtest/integration/ScalaWebTestBaseSpec.scala b/integration_test/src/it/scala/org/scalawebtest/integration/ScalaWebTestBaseSpec.scala index 05af794..f08063e 100755 --- a/integration_test/src/it/scala/org/scalawebtest/integration/ScalaWebTestBaseSpec.scala +++ b/integration_test/src/it/scala/org/scalawebtest/integration/ScalaWebTestBaseSpec.scala @@ -25,7 +25,7 @@ trait ScalaWebTestBaseSpec extends IntegrationFlatSpec with AemTweaks with FormB override val host = "http://localhost:8080" override val loginPath = "/fakeLogin.jsp" - override val projectRoot = "/" + override val projectRoot = "" override def loginTimeout = Timeout(5 seconds) } diff --git a/integration_test/src/it/scala/org/scalawebtest/integration/gauge/ContainsSpec.scala b/integration_test/src/it/scala/org/scalawebtest/integration/gauge/ContainsSpec.scala old mode 100644 new mode 100755 index 4a61e54..11d0a0b --- a/integration_test/src/it/scala/org/scalawebtest/integration/gauge/ContainsSpec.scala +++ b/integration_test/src/it/scala/org/scalawebtest/integration/gauge/ContainsSpec.scala @@ -18,8 +18,9 @@ import org.scalawebtest.core.gauge.Gauge.fits import org.scalawebtest.integration.ScalaWebTestBaseSpec class ContainsSpec extends ScalaWebTestBaseSpec { + path = "/navigation.jsp" + "Contains" should "loosely match attributes" in { - navigateTo("/navigation.jsp") fits(