MainTestClass.scala
package samples.test.Tests

import java.time.Duration
import java.util.concurrent.TimeUnit

import scala.collection.JavaConverters.asScalaSetConverter
import scala.language.postfixOps
import scala.util.Failure
import scala.util.Success
import scala.util.Try

import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.support.ui.WebDriverWait
import org.openqa.selenium.By
import java.time.Duration

import scala.collection.JavaConverters.asScalaBufferConverter
import scala.concurrent.Future
import scala.concurrent.Await
import scala.util.Random

import org.jsoup.Jsoup
import org.openqa.selenium.By
import org.testng.annotations._
import PageObjectModel.MainPage
import PageObjectModel.WebDriverInit
import de.svenjacobs.loremipsum.LoremIpsum
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.support.ui.WebDriverWait
import org.openqa.selenium.ElementClickInterceptedException
import org.openqa.selenium.WebElement
import org.scalatest.Matchers._
import org.scalatest.testng.TestNGSuiteLike
import org.testng.Reporter
import org.openqa.selenium.Keys

class MainTestClass extends TestNg with ElementImplicits with ExtendedMethods with Utils {

	case class DbData(entryId: Int, vendorId: Int, companyName: String, Airport: String, ableToDoSmall: Int, ableMedium: Int, ableToDoHeavy: Int, remarksAndLimitations: String, dateTime: String)

	def startBrowser(): WebDriverInit = {
		val init = new WebDriverInit()
		init.startBrowser()
		init
	}

	def refreshPage()(implicit driver: ChromeDriver): Unit = {
		driver.navigate().refresh()
	}

	def login()(implicit mainPage: MainPage, driver: ChromeDriver, dataSenderPage: DataSenderPage): Unit = {
		mainPage.webDriverWait(mainPage.usernameInput.nonEmpty)
		mainPage.usernameInput.sendKeys("marek_handling")
		mainPage.passwordInput.sendKeys("Bajkajefikce")
		mainPage.loginButton.click()
		mainPage.webDriverWait(dataSenderPage.ableSmallBox.nonEmpty)
	}

	def login(username: String, password: String)(implicit mainPage: MainPage, driver: ChromeDriver, dataSenderPage: DataSenderPage): Unit = {
		mainPage.webDriverWait(mainPage.usernameInput.nonEmpty)
		mainPage.usernameInput.sendKeys(username)
		mainPage.passwordInput.sendKeys(password)
		mainPage.loginButton.click()
		mainPage.webDriverWait(dataSenderPage.ableSmallBox.nonEmpty)
	}

	var antiCycle: Int = 0

	def tryClick(webElement: WebElement): Unit = {
		Try {
			webElement.click()
		} match {
			case Failure(f) =>
				Thread.sleep(1000)
				if (antiCycle == 60) throw new Exception(f)
				tryClick(webElement)
			case Success(_) =>
		}
	}


	@Test()
	def test1(): Unit = {
		val browser = startBrowser()
		implicit val driver: ChromeDriver = browser.driver
		implicit val mainPage: MainPage = new MainPage()
		implicit val dataSenderPage: DataSenderPage = mainPage.dataSenderPage

		/** Přihlášení */
		login("bot_handler_11","Jatonepsalhomer")

		for (x <- 1 to 100) {

			val randonm1 = mainPage.randonm1
			val vendorId = 11
			Reporter.log("val) random : " + randonm1)

			/** smaže data */
			clearAllInputs()

			/** vyplní random data */
			fillAllInputsWithOneVariable(randonm1.toString)
			val lorem = loremIpsum(10)
			dataSenderPage.remarks.sendKeys(lorem)
			import java.util.concurrent.TimeUnit
			//driver.manage.timeouts.implicitlyWait(1, TimeUnit.SECONDS)

			/** získání tabulky před odesláním dat */
			val beforeInsert = parseDbData()

			/** Odeslání dat + čekání než vyskočí dialog */
			//tryClick(dataSenderPage.submitHandler)
			dataSenderPage.submitHandler.sendKeys(Keys.ENTER)
			webDriverWait(dataSenderPage.successInsert.getText == "Everything Well Received!")

			refreshPage()


			//dataSenderPage.webDriverWait(dataSenderPage.tableAbleSmall.nonEmpty)
			//webDriverWait(parseDbData().nonEmpty && parseDbData().head.entryId == (beforeInsert.head.entryId + 1))

			/** získání dat a porovnání posledního záznamu */
			val afterInsert = parseDbData()
			val afterInsert_lastInsert = afterInsert.head

			if (afterInsert_lastInsert.remarksAndLimitations != lorem || afterInsert_lastInsert.vendorId != vendorId || afterInsert_lastInsert.ableToDoSmall != randonm1 || afterInsert_lastInsert.ableMedium != randonm1 || afterInsert_lastInsert.ableToDoHeavy != randonm1) {

				Reporter.log(s"Zánam číslo[$x] : " + afterInsert_lastInsert)

				afterInsert_lastInsert.remarksAndLimitations should be(lorem)
				afterInsert_lastInsert.vendorId should be(vendorId)
				afterInsert_lastInsert.ableToDoSmall should be(randonm1)
				afterInsert_lastInsert.ableMedium should be(randonm1)
				afterInsert_lastInsert.ableToDoHeavy should be(randonm1)

				Reporter.log(s"v tabluce: " + dataSenderPage.tableAbleSmall.head.getText)
				Reporter.log(s"4) Test1")
			}
		}
		browser.closeBrowser()

	}


	 @Test()
	 def test2(): Unit = {
		 val browser = startBrowser()
		 implicit val driver: ChromeDriver = browser.driver
		 implicit val mainPage: MainPage = new MainPage()
		 implicit val dataSenderPage: DataSenderPage = mainPage.dataSenderPage

		 /** Přihlášení */
		 login("bot_handler_12","Jatonepsalhomer")

		 for (x <- 1 to 100) {

			 val randonm1 = mainPage.randonm1
			 val vendorId = 12
			 Reporter.log("val) random : " + randonm1)

			 /** smaže data */
			 clearAllInputs()

			 /** vyplní random data */
			 fillAllInputsWithOneVariable(randonm1.toString)
			 val lorem = loremIpsum(10)
			 dataSenderPage.remarks.sendKeys(lorem)

			 /** získání tabulky před odesláním dat */
			 val beforeInsert = parseDbData()

			 /** Odeslání dat + čekání než vyskočí dialog */
			 //tryClick(dataSenderPage.submitHandler)
			 dataSenderPage.submitHandler.sendKeys(Keys.ENTER)
			 webDriverWait(dataSenderPage.successInsert.getText == "Everything Well Received!")

			 refreshPage()


			 dataSenderPage.webDriverWait(dataSenderPage.tableAbleSmall.nonEmpty)
			 webDriverWait(parseDbData().nonEmpty)

			 /** získání dat a porovnání posledního záznamu */
			 val afterInsert = parseDbData()
			 val afterInsert_lastInsert = afterInsert.head

			 if (afterInsert_lastInsert.remarksAndLimitations != lorem || afterInsert_lastInsert.vendorId != vendorId || afterInsert_lastInsert.ableToDoSmall != randonm1 ||  afterInsert_lastInsert.ableMedium != randonm1 || afterInsert_lastInsert.ableToDoHeavy != randonm1) {

				 Reporter.log(s"Zánam číslo[$x] : " + afterInsert_lastInsert)

				 afterInsert_lastInsert.remarksAndLimitations should be(lorem)
				 afterInsert_lastInsert.vendorId should be(vendorId)
				 afterInsert_lastInsert.ableToDoSmall should be(randonm1)
				 afterInsert_lastInsert.ableMedium should be(randonm1)
				 afterInsert_lastInsert.ableToDoHeavy should be(randonm1)

				 Reporter.log(s"v tabluce: " + dataSenderPage.tableAbleSmall.head.getText)
				 Reporter.log(s"4) Test2")
			 }
		 }


		 browser.closeBrowser()
	 }

	@Test()
	def test3(): Unit = {
		val browser = startBrowser()
		implicit val driver: ChromeDriver = browser.driver
		implicit val mainPage: MainPage = new MainPage()
		implicit val dataSenderPage: DataSenderPage = mainPage.dataSenderPage

		/** Přihlášení */
		login("bot_handler13", "Jatonepsalhomer")

		for (x <- 1 to 100) {

			val randonm1 = mainPage.randonm1
			val vendorId = 13
			Reporter.log("val) random : " + randonm1)

			/** smaže data */
			clearAllInputs()

			/** vyplní random data */
			fillAllInputsWithOneVariable(randonm1.toString)
			val lorem = loremIpsum(10)
			dataSenderPage.remarks.sendKeys(lorem)

			/** získání tabulky před odesláním dat */
			val beforeInsert = parseDbData()

			/** Odeslání dat + čekání než vyskočí dialog */
			//tryClick(dataSenderPage.submitHandler)
			dataSenderPage.submitHandler.sendKeys(Keys.ENTER)
			webDriverWait(dataSenderPage.successInsert.getText == "Everything Well Received!")

			refreshPage()


			dataSenderPage.webDriverWait(dataSenderPage.tableAbleSmall.nonEmpty)
			webDriverWait(parseDbData().nonEmpty)

			/** získání dat a porovnání posledního záznamu */
			val afterInsert = parseDbData()
			val afterInsert_lastInsert = afterInsert.head

			if (afterInsert_lastInsert.remarksAndLimitations != lorem || afterInsert_lastInsert.vendorId != vendorId || afterInsert_lastInsert.ableToDoSmall != randonm1 || afterInsert_lastInsert.ableMedium != randonm1 || afterInsert_lastInsert.ableToDoHeavy != randonm1) {

				Reporter.log(s"Zánam číslo[$x] : " + afterInsert_lastInsert)

				afterInsert_lastInsert.remarksAndLimitations should be(lorem)
				afterInsert_lastInsert.vendorId should be(vendorId)
				afterInsert_lastInsert.ableToDoSmall should be(randonm1)
				afterInsert_lastInsert.ableMedium should be(randonm1)
				afterInsert_lastInsert.ableToDoHeavy should be(randonm1)

				Reporter.log(s"v tabluce: " + dataSenderPage.tableAbleSmall.head.getText)
				Reporter.log(s"4) Test2")
			}
		}


		browser.closeBrowser()
	}


	@Test()
	def test4(): Unit = {
		val browser = startBrowser()
		implicit val driver: ChromeDriver = browser.driver
		implicit val mainPage: MainPage = new MainPage()
		implicit val dataSenderPage: DataSenderPage = mainPage.dataSenderPage

		/** Přihlášení */
		login("bot_handler_14", "Jatonepsalhomer")

		for (x <- 1 to 100) {

			val randonm1 = mainPage.randonm1
			val vendorId = 14
			Reporter.log("val) random : " + randonm1)

			/** smaže data */
			clearAllInputs()

			/** vyplní random data */
			fillAllInputsWithOneVariable(randonm1.toString)
			val lorem = loremIpsum(10)
			dataSenderPage.remarks.sendKeys(lorem)

			/** získání tabulky před odesláním dat */
			val beforeInsert = parseDbData()

			/** Odeslání dat + čekání než vyskočí dialog */
			//tryClick(dataSenderPage.submitHandler)
			dataSenderPage.submitHandler.sendKeys(Keys.ENTER)
			webDriverWait(dataSenderPage.successInsert.getText == "Everything Well Received!")

			refreshPage()


			dataSenderPage.webDriverWait(dataSenderPage.tableAbleSmall.nonEmpty)
			webDriverWait(parseDbData().nonEmpty)

			/** získání dat a porovnání posledního záznamu */
			val afterInsert = parseDbData()
			val afterInsert_lastInsert = afterInsert.head

			if (afterInsert_lastInsert.remarksAndLimitations != lorem || afterInsert_lastInsert.vendorId != vendorId || afterInsert_lastInsert.ableToDoSmall != randonm1 || afterInsert_lastInsert.ableMedium != randonm1 || afterInsert_lastInsert.ableToDoHeavy != randonm1) {

				Reporter.log(s"Zánam číslo[$x] : " + afterInsert_lastInsert)

				afterInsert_lastInsert.remarksAndLimitations should be(lorem)
				afterInsert_lastInsert.vendorId should be(vendorId)
				afterInsert_lastInsert.ableToDoSmall should be(randonm1)
				afterInsert_lastInsert.ableMedium should be(randonm1)
				afterInsert_lastInsert.ableToDoHeavy should be(randonm1)

				Reporter.log(s"v tabluce: " + dataSenderPage.tableAbleSmall.head.getText)
				Reporter.log(s"4) Test2")
			}
		}


		browser.closeBrowser()
	}

	@Test()
	def test5(): Unit = {
		val browser = startBrowser()
		implicit val driver: ChromeDriver = browser.driver
		implicit val mainPage: MainPage = new MainPage()
		implicit val dataSenderPage: DataSenderPage = mainPage.dataSenderPage

		/** Přihlášení */
		login("bot_handler_15", "Jatonepsalhomer")

		for (x <- 1 to 100) {

			val randonm1 = mainPage.randonm1
			val vendorId = 15
			Reporter.log("val) random : " + randonm1)

			/** smaže data */
			clearAllInputs()

			/** vyplní random data */
			fillAllInputsWithOneVariable(randonm1.toString)
			val lorem = loremIpsum(10)
			dataSenderPage.remarks.sendKeys(lorem)

			/** získání tabulky před odesláním dat */
			val beforeInsert = parseDbData()

			/** Odeslání dat + čekání než vyskočí dialog */
			//tryClick(dataSenderPage.submitHandler)
			dataSenderPage.submitHandler.sendKeys(Keys.ENTER)
			webDriverWait(dataSenderPage.successInsert.getText == "Everything Well Received!")

			refreshPage()


			dataSenderPage.webDriverWait(dataSenderPage.tableAbleSmall.nonEmpty)
			webDriverWait(parseDbData().nonEmpty)

			/** získání dat a porovnání posledního záznamu */
			val afterInsert = parseDbData()
			val afterInsert_lastInsert = afterInsert.head

			if (afterInsert_lastInsert.remarksAndLimitations != lorem || afterInsert_lastInsert.vendorId != vendorId || afterInsert_lastInsert.ableToDoSmall != randonm1 || afterInsert_lastInsert.ableMedium != randonm1 || afterInsert_lastInsert.ableToDoHeavy != randonm1) {

				Reporter.log(s"Zánam číslo[$x] : " + afterInsert_lastInsert)

				afterInsert_lastInsert.remarksAndLimitations should be(lorem)
				afterInsert_lastInsert.vendorId should be(vendorId)
				afterInsert_lastInsert.ableToDoSmall should be(randonm1)
				afterInsert_lastInsert.ableMedium should be(randonm1)
				afterInsert_lastInsert.ableToDoHeavy should be(randonm1)

				Reporter.log(s"v tabluce: " + dataSenderPage.tableAbleSmall.head.getText)
				Reporter.log(s"4) Test2")
			}
		}


		browser.closeBrowser()
	}

		/**
	 * @Test()
	 * def test3(): Unit = {
	 * doSomething()
	 * Reporter.log(s"4) Test3")
	 * }
	 * @Test()
	 * def test4(): Unit = {
	 * doSomething()
	 * Reporter.log(s"4) Test4")
	 * }
	 * @Test()
	 * def test5(): Unit = {
	 * doSomething()
	 * Reporter.log(s"4) Test5")
	 * }
	 *
	 */

	def parseDbData()(implicit driver: ChromeDriver): List[DbData] = {
		def doc = Jsoup.parse(driver.getPageSource)

		def rows = doc.select("#table_div tbody > tr").asScala.toList

		val dbData: List[DbData] = for (row <- rows) yield {
			val entryId = row.select(" > td ").first().text()
			val VendorId = row.select("td + td").first().text()
			val companyName = row.select("td + td + td").first().text()
			val Airport = row.select("td + td + td + td").first().text()
			val ableToDoSmall = row.select("td + td + td + td + td").first().text()
			val ableMedium = row.select("td + td + td + td + td + td").first().text()
			val ableToDoHeavy = row.select("td + td + td + td + td + td + td").first().text()
			val remarksAndLimitations = row.select("td + td + td + td + td + td + td + td").first().text()
			val dateTime = row.select("td + td + td + td + td + td + td + td + td").first().text()

			DbData(entryId.toInt, VendorId.toInt, companyName, Airport, ableToDoSmall.toInt, ableMedium.toInt, ableToDoHeavy.toInt, remarksAndLimitations, dateTime)
		}
		dbData
	}
}





abstract class TestNg extends TestNGSuiteLike

trait Utils {

	def webDriverWait[A](f: => Boolean, timeOut: Int = 60, defaultPollingInMillis: Int = 500)(implicit driver: ChromeDriver): Unit = {
		val wait = new WebDriverWait(driver, timeOut)
		wait.pollingEvery(Duration.ZERO.plusMillis(defaultPollingInMillis)).until(Unit => f)
	}

	def Xpath(value: String): By = {
		By.xpath(value)
	}

	def Css(value: String): By = {
		By.cssSelector(value)
	}

	def randonm1: Int = Random.shuffle((1 to 10).toList).head

	def loremIpsum(length: Int): String = {
		val lorem = new LoremIpsum
		lorem.getWords(length)
	}
}




//  def doSomething(): Unit = {
//    val init = startBrowser()
//    val driver = init.driver
//    Reporter.log("1) Získání pageSource")
//    val pageSource = driver.getPageSource
//    Reporter.log("2) Parse a Získání všech cards [news-header]")
//    val czuNews = parseNewsCards(pageSource)
//    val cardsSize = czuNews.size
//    Reporter.log(s"3) Celkový počet cards je ${cardsSize}, základní počet má být 8.")
//    cardsSize should be(8)
//    init.closeBrowser()
//  }