import com.weEat.controllers.UserController import javax.inject.Inject import play.api.test.Helpers._ import play.api.test.FakeRequest import play.api.libs.json.Json import org.openqa.selenium.By import org.scalatest.{Assertion,BeforeAndAfterAll,BeforeAndAfterEach} import org.scalatestplus.play._ import org.scalatestplus.play.guice.GuiceOneServerPerSuite import com.weEat.shared.models.User import scala.concurrent.{Future,blocking} import scala.concurrent.duration._ import scala.language.postfixOps import java.util.concurrent.TimeoutException import org.bson.types.ObjectId class IntegrationSpec @Inject()( userController: UserController ) extends PlaySpec with BeforeAndAfterAll with BeforeAndAfterEach with GuiceOneServerPerSuite with AllBrowsersPerTest { val users = Seq( (User(new ObjectId(), "test", "user", "tuser@sample.org"), "password"), (User(new ObjectId(), "another", "user", "usert@sample.org"), "password") ) override def beforeAll() = { val Some(resp) = route(app, FakeRequest(PUT, "/v1/user/").withJsonBody( Json.parse(s"""|{ | "fname": "${users(0)._1.fname}", | "lname": "${users(0)._1.lname}", | "email": "${users(0)._1.email}", | "password": "${users(0)._2}" |}""".stripMargin) )) status(resp) mustEqual OK } override def afterAll() = { implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global Future.sequence(Seq( userController.deleteUser(users(0)._1._id), )).map { (deletes) => deletes must matchPattern { case Seq(_) => } } // val Some(resp) = route(app, FakeRequest(DELETE, s"/v1/user/${users(0)._id}")) // status(resp) mustEqual OK // val Some(resp) = route(app, FakeRequest(DELETE, s"/v1/user/${users(1)._id}")) // status(resp) mustEqual OK } override lazy val browsers = Vector( FirefoxInfo(firefoxProfile), //ChromeInfo ) val address = s"http://localhost:$port" /* Will repeatedly attempt to test until a result is returned. * A None value implies the test is not yet ready to run and will be attempted * again after the frequency has passed.. * * A Some value means the test has completed with the contained assertion * result. */ def poll( test: () => Option[Assertion], frequency: Duration = 100.millisecond ): Future[Assertion] = { test() match { case Some(result) => Future.successful(result) case None => { blocking { Thread.sleep(frequency.toMillis) } poll(test, frequency) } } } def waitForReady[T]( timeout: Duration = 1 minute, period: Duration = 100 millisecond )(fn: => T): Future[T] = if (executeScript("return jQuery.active == 0 && selAsyncCount == 0;").asInstanceOf[Boolean]) Future.successful(fn) else if (timeout < 0.second) Future.failed(new TimeoutException()) else { blocking { Thread.sleep(period.toMillis) } waitForReady(timeout - period, period)(fn) } def sharedTests(browser: BrowserInfo) = { "The register menu" must { "display when register button is clicked " + browser.name in { go to address click on id("btn-signup") waitForReady() { click on id("view-register").webElement.findElement(By.xpath("./..")) //id("content").webElement.getText mustEqual ("") } } def testUserList() = { val Some(resp) = route(app, FakeRequest(GET, "/v1/user/")) status(resp) mustEqual OK contentAsJson(resp).as[Seq[String]] must matchPattern { case Seq(user1, user2) => } } "accept a new user " + browser.name in { go to address click on id("btn-signup") waitForReady() { textField("email").value = users(1)._1.email name("password").webElement.sendKeys(users(1)._2) name("password2").webElement.sendKeys(users(1)._2) textField("fname").value = users(1)._1.fname textField("lname").value = users(1)._1.lname click on cssSelector("*[data-cb='success']") waitForReady() { find("#view-register") must be (None) id("btn-logout").webElement must be ("displayed") // id("content").webElement.getText // .mustEqual(s"Hello, ${users(1)._1.fname} ${users(1)._1.lname}!") // testUserList() } } } "reject a used email " + browser.name in { go to address click on id("btn-signup") waitForReady() { textField("email").value = users(0)._1.email name("password").webElement.sendKeys("_"+users(0)._2) name("password2").webElement.sendKeys("_"+users(0)._2) textField("fname").value = "_"+users(0)._1.fname textField("lname").value = "_"+users(0)._1.lname click on cssSelector("*[data-cb='success']") waitForReady() { cssSelector(".alert-danger").webElement.getText .mustEqual("Error: This email address is already registered.") id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") testUserList() } } } "reject an invalid email " + browser.name in { go to address click on id("btn-signup") waitForReady() { textField("email").value = "hello World!" name("password").webElement.sendKeys("_"+users(0)._2) name("password2").webElement.sendKeys("_"+users(0)._2) textField("fname").value = "_"+users(0)._1.fname textField("lname").value = "_"+users(0)._1.lname click on cssSelector("*[data-cb='success']") waitForReady() { cssSelector(".alert-danger").webElement.getText .mustEqual("Error: Invalid email.") id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") testUserList() } } } "reject a password below 8 characters " + browser.name in { go to address click on id("btn-signup") waitForReady() { textField("email").value = "_"+users(0)._1.email name("password").webElement.sendKeys("1234567") name("password2").webElement.sendKeys("1234567") textField("fname").value = "_"+users(0)._1.fname textField("lname").value = "_"+users(0)._1.lname click on cssSelector("*[data-cb='success']") waitForReady() { cssSelector(".alert-danger").webElement.getText .mustEqual("Error: Password too short (Minimum 8 characters).") id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") testUserList() } } } "reject a non-matching passwords " + browser.name in { go to address click on id("btn-signup") waitForReady() { textField("email").value = "_"+users(0)._1.email name("password").webElement.sendKeys(users(0)._2) name("password2").webElement.sendKeys("_"+users(0)._2) textField("fname").value = "_"+users(0)._1.fname textField("lname").value = "_"+users(0)._1.lname click on cssSelector("*[data-cb='success']") waitForReady() { cssSelector(".alert-danger").webElement.getText .mustEqual("Error: Passwords do not match.") id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") testUserList() } } } } "The login menu" must { "display when login button is clicked " + browser.name in { go to address click on id("btn-login") waitForReady() { click on id("view-login").webElement.findElement(By.xpath("./..")) id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") } } "accept user created from API " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = users(0)._1.email name("password").webElement.sendKeys(users(0)._2) click on cssSelector("*[data-cb='success']") waitForReady() { find("#view-login") must be (None) id("btn-logout").webElement must be ("displayed") // id("content").webElement.getText // .mustEqual(s"Hello, ${users(0)._1.fname} ${users(0)._1.lname}!") } } } "accept user created from UI " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = users(1)._1.email name("password").webElement.sendKeys(users(1)._2) click on cssSelector("*[data-cb='success']") waitForReady() { find("#view-login") must be (None) id("btn-logout").webElement must be ("displayed") // id("content").webElement.getText // .mustEqual(s"Hello, ${users(1)._1.fname} ${users(1)._1.lname}!") } } } "reject an incorrect email " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = "_"+users(1)._1.email name("password").webElement.sendKeys(users(0)._2) click on cssSelector("*[data-cb='success']") waitForReady() { cssSelector(".alert-danger").webElement.getText .mustEqual("Error: Invalid client or client is not authorized") id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") } } } "reject an incorrect password " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = users(1)._1.email name("password").webElement.sendKeys("_"+users(0)._2) click on cssSelector("*[data-cb='success']") waitForReady() { cssSelector(".alert-danger").webElement.getText .mustEqual("Error: Invalid client or client is not authorized") id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") } } } "reject an incorrect email and password " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = "_"+users(1)._1.email name("password").webElement.sendKeys("_"+users(0)._2) click on cssSelector("*[data-cb='success']") waitForReady() { cssSelector(".alert-danger").webElement.getText .mustEqual("Error: Invalid client or client is not authorized") id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") } } } "maintain login info across refresh " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = users(1)._1.email name("password").webElement.sendKeys(users(1)._2) click on cssSelector("*[data-cb='success']") waitForReady() { go to address waitForReady() { find("#view-login") must be (None) id("btn-logout").webElement must be ("displayed") // id("content").webElement.getText // .mustEqual(s"Hello, ${users(1)._1.fname} ${users(1)._1.lname}!") id("btn-logout").webElement must be ("displayed") } } } } } "The logout button" must { "not display when not logged in " + browser.name in { go to address waitForReady() { id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") } } "display when logged in" + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = users(0)._1.email name("password").webElement.sendKeys(users(0)._2) click on cssSelector("*[data-cb='success']") waitForReady() { id("btn-logout").webElement must be ("displayed") } } } "remove user information when clicked " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = users(0)._1.email name("password").webElement.sendKeys(users(0)._2) click on cssSelector("*[data-cb='success']") waitForReady() { click on id("btn-logout") waitForReady() { id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") } } } } "remove stored user information when clicked " + browser.name in { go to address click on id("btn-login") waitForReady() { textField("email").value = users(0)._1.email name("password").webElement.sendKeys(users(0)._2) click on cssSelector("*[data-cb='success']") waitForReady() { click on id("btn-logout") waitForReady() { go to address id("btn-logout").webElement mustNot be ("displayed") //id("content").webElement.getText mustEqual("") } } } } } } }