Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jc duosb #1517

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ case class Button(queryString: QueryString)(implicit webDriver: WebDriver)
def isStateDisabled: Boolean = { awaitVisible(); getState == disabledState }

def awaitEnabledState(): Unit = awaitState(enabledState)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ case class Checkbox(queryString: QueryString)(implicit webDriver: WebDriver) ext
def ensureUnchecked(): Unit = {
checkbox(query).clear()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@ case class TabBar(private val queryString: QueryString = TestId("tabs"))(implici
await condition (invisibleSpinner)
}

// Making a new variable called anaquery (analysis tab)
// val anaquery = CssSelectorQuery("div[data-test-id='Analysis-tab'])")
// def mytest(): Unit ={
// //anaquery.findElement.get.underlying.getText()
// anaquery.findElement.get.text()
// System.out.print("this is my output" + anaquery)
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package org.broadinstitute.dsde.firecloud.fixture
import org.broadinstitute.dsde.firecloud.FireCloudConfig
import org.scalatest.concurrent.{Eventually, ScaledTimeSpans}
import org.broadinstitute.dsde.firecloud.page.AuthenticatedPage
import org.broadinstitute.dsde.firecloud.page.duos.{DuosHomePage, DuosLoginPage}
import org.broadinstitute.dsde.firecloud.page.user.{RegistrationPage, SignInPage, TermsOfServicePage}
import org.broadinstitute.dsde.firecloud.page.workspaces.WorkspaceListPage
import org.broadinstitute.dsde.workbench.auth.AuthTokenScopes
Expand All @@ -16,7 +17,8 @@ import org.broadinstitute.dsde.workbench.service.util.Retry.retry
import scala.concurrent.duration._
import scala.util.Try

trait UserFixtures extends CleanUp with ScaledTimeSpans with Eventually { self: WebBrowserSpec with TestSuite =>
trait UserFixtures extends CleanUp with ScaledTimeSpans with Eventually {
self: WebBrowserSpec with TestSuite =>

/**
* "Signs in" to FireCloud with an access token, bypassing the Google sign-in flow. Assumes the
Expand All @@ -32,7 +34,7 @@ trait UserFixtures extends CleanUp with ScaledTimeSpans with Eventually { self:
* Assumes the user is already registered so hands the test code a ready WorkspaceListPage.
*/
def withScopedSignIn(user: Credentials, scopes: Seq[String])
(testCode: WorkspaceListPage => Any)(implicit webDriver: WebDriver): Unit = {
(testCode: WorkspaceListPage => Any)(implicit webDriver: WebDriver): Unit = {
withSignIn(user, new WorkspaceListPage, scopes)(testCode)
}

Expand All @@ -45,20 +47,39 @@ trait UserFixtures extends CleanUp with ScaledTimeSpans with Eventually { self:
withSignInReal(user, new WorkspaceListPage)(testCode)
}

/**
* Signs in to FireCloud using the Google sign-in flow. Assumes the user is already registered so
* hands the test code a ready WorkspaceListPage.
*/
def withSignInDuos(user: Credentials)
(testCode: DuosHomePage => Any)(implicit webDriver: WebDriver): Unit = {
withSignInDuos(user, new DuosHomePage())(testCode)
}

def withSignInDuos[T <: AuthenticatedPage](user: Credentials, page: T)
(testCode: T => Any)
(implicit webDriver: WebDriver): Unit = {

logger.info(s"withSignInDuos: ${user.email} ...")
executeTestCodeWithSignIn(user, {
new DuosLoginPage("https://duos.dsde-dev.broadinstitute.org/#/login").open.signIn(user.email, user.password)
}, page, testCode)
}

/**
* "Signs in" to FireCloud with an access token, bypassing the Google sign-in flow. Assumes the
* user is not registered and returns a ready TermsOfServicePage.
*/
def withSignInNewUser(user: Credentials)
(testCode: RegistrationPage => Any)(implicit webDriver: WebDriver): Unit = {
withSignIn(user, new TermsOfServicePage) { tosPage =>
register cleanUp executeAsyncScript("window.rejectToS(arguments[arguments.length - 1])")
withSignIn(user, new TermsOfServicePage) { tosPage =>
register cleanUp executeAsyncScript("window.rejectToS(arguments[arguments.length - 1])")

tosPage.accept()
tosPage.accept()

val registrationPage = await ready new RegistrationPage
val registrationPage = await ready new RegistrationPage

testCode(registrationPage)
testCode(registrationPage)

}
}
Expand All @@ -72,14 +93,14 @@ trait UserFixtures extends CleanUp with ScaledTimeSpans with Eventually { self:
executeTestCodeWithSignIn(user, {
// workaround for failed forceSignedIn
var counter = 0
retry(Seq.fill(2)(1.seconds)) ({
retry(Seq.fill(2)(1.seconds))({
logger.info(s"withSignIn (${user.email}) opening SignInPage ...")
new SignInPage(FireCloudConfig.FireCloud.baseUrl).open
logger.info(s"withSignIn (${user.email}) executing script forceSignedIn ...")
val js = s"window.forceSignedIn('${user.makeAuthToken(scopes).value}')"
executeScript(js)
if (counter > 0) logger.warn(s"Retrying execute JavaScript forceSignedIn(): value = $js")
counter +=1
counter += 1
try {
logger.info(s"withSignIn (${user.email}) awaiting page ready ...")
page.awaitReady()
Expand All @@ -101,9 +122,9 @@ trait UserFixtures extends CleanUp with ScaledTimeSpans with Eventually { self:
}, page, testCode)
}

private def withSignInReal[T <: AuthenticatedPage](user: Credentials, page: T)
(testCode: T => Any)
(implicit webDriver: WebDriver): Unit = {
def withSignInReal[T <: AuthenticatedPage](user: Credentials, page: T)
(testCode: T => Any)
(implicit webDriver: WebDriver): Unit = {

logger.info(s"withSignInReal: ${user.email} ...")
executeTestCodeWithSignIn(user, {
Expand All @@ -126,7 +147,7 @@ trait UserFixtures extends CleanUp with ScaledTimeSpans with Eventually { self:
testCode(page)

logger.info(s"executeTestCodeWithSignIn (${user.email}) signing out ...")
try page.signOut() catch nonFatalAndLog(s"ERROR logging out user: ${user.email}")
//try page.signOut() catch nonFatalAndLog(s"ERROR logging out user: ${user.email}")
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.broadinstitute.dsde.firecloud.page.duos

import org.broadinstitute.dsde.firecloud.page.{BaseFireCloudPage, PageUtil}
import org.openqa.selenium.WebDriver

/**
* The DuosHomePage class should be the page where I have different methods to verify the homepage
* after logging in.
*
* @param webDriver
*/
class DuosHomePage(implicit webDriver: WebDriver) extends BaseFireCloudPage
with PageUtil[DuosHomePage] {

lazy override val url = "https://duos.dsde-dev.broadinstitute.org/#/login"

override def awaitReady(): Unit = {
super.awaitReady()
await condition {
val column = find(cssSelector("table th:nth-child(2)"))
var f: Boolean = false
if (column.isDefined) {
val txt = column.get.underlying.getText
f = txt.equalsIgnoreCase("Dataset ID")
}
f
}
}

/**
* Search for a dataset ID on the searchbar and advance to the next page.
*/
def datasetSearch(): Unit = {
goTo("https://duos.dsde-dev.broadinstitute.org/#/dataset_catalog")
val searchfor = "DUOS-000003"
val searchBar = cssSelector("input[ng-model='searchDataset']")
searchBar.findElement.get.underlying.click()
searchBar.findElement.get.asInstanceOf[ValueElement].value_=(searchfor)
val check = cssSelector("label[class='regular-checkbox rp-choice-questions']")
check.findElement.get.underlying.click()
val applyforaccess = cssSelector("button[ng-show='isResearcher']")
applyforaccess.findElement.get.underlying.click()
Thread.sleep(1000)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package org.broadinstitute.dsde.firecloud.page.duos

import org.broadinstitute.dsde.firecloud.FireCloudView
import org.broadinstitute.dsde.firecloud.component._
import org.broadinstitute.dsde.firecloud.page.PageUtil
import org.broadinstitute.dsde.workbench.config.Credentials
import org.broadinstitute.dsde.workbench.service.test.WebBrowserUtil
import org.openqa.selenium.{TimeoutException, WebDriver}
import org.scalatest.selenium.{Page, WebBrowser}

import scala.util.{Failure, Success, Try}

/**
* Page class for the page displayed when accessing FireCloud when not signed in.
*/
class DuosLoginPage(val baseUrl: String)(implicit webDriver: WebDriver) extends FireCloudView with Page with PageUtil[DuosLoginPage] {

case class GoogleSignInButton(queryString: CSSQuery)(implicit webDriver: WebDriver) extends Component(queryString) with Clickable {
override def awaitReady(): Unit = {
val signInTextCsspath = s"${queryString.text}"
log.info(s"GoogleSignInButton starting ready-wait for $signInTextCsspath ...")
await condition {
val signInText = findAll(cssSelector(signInTextCsspath))
signInText.exists(_.text.contains("Sign in with Google"))
}
}
}

override def awaitReady(): Unit = {
log.info("DuosLoginPage.awaitReady starting to wait for signInButton ... ")

Try(signInButton awaitReady()) match {
case Success(_) =>
log.info("DuosLoginPage.awaitReady believes signInButton is ready; sleeping for 500ms ... ")
Thread.sleep(500)
case Failure(f) =>
log.error(s"DuosLoginPage timed out waiting for signInButton to be ready: ${f.getMessage}")
throw (f)
}
}

lazy override val url: String = "https://duos.dsde-dev.broadinstitute.org/#/login"

private val signInButton = GoogleSignInButton(CSSQuery(".abcRioButtonContentWrapper span[id]:first-child"))

def isOpen = signInButton.isVisible

/**
* Sign in to Duos
*/
def signIn(email: String, password: String): Unit = {
val popup = beginSignIn()
popup.signIn(email, password)
//TODO
//await enabled testId("account-dropdown")
}

/**
* Handles the pre-sign-in dance of switching Selenium's focus to Google's
* sign-in pop-up window.
*
* @return a new GoogleSignInPopup
*/
private def beginSignIn(): GoogleSignInPopup = {
val initialWindowHandles = windowHandles

signInButton.doClick()
Thread.sleep(1000)

await condition (windowHandles.size == 2)

val popupWindowHandle = (windowHandles -- initialWindowHandles).head

switch to window(popupWindowHandle)
new GoogleSignInPopup().awaitLoaded()
}
}


class GoogleSignInPopup(implicit webDriver: WebDriver) extends WebBrowser with WebBrowserUtil {

def awaitLoaded(): GoogleSignInPopup = {
Try {
await condition(id("identifierLink").findElement.exists(_.isDisplayed)
|| id("identifierId").findElement.exists(_.isEnabled)
|| id("Email").findElement.exists(_.isDisplayed), 10) // One Account All of Google popup
} match {
case Success(_) =>
find(id("identifierLink")) foreach { link =>
click on link
await visible id("identifierId")
}
case Failure(t) => throw new TimeoutException("Timed out (10 seconds) waiting for Google SignIn Popup.", t)
}

this
}

/**
* Signs in to Google to authenticate for FireCloud.
*/
def signIn(email: String, password: String): Unit = {
(id("Email").findElement.isDefined) match {
case true => oneAccountSignIn(email, password)
case false => normalSignIn(email, password)
}
returnFromSignIn()
}

private def normalSignIn(email: String, password: String): Unit = {
await enabled id("identifierId")
emailField(id("identifierId")).value = email
pressKeys("\n")

await enabled id("passwordNext")
await enabled name("password")
/*
* The Google real SignIn: animation transition from username to password freezes when other web browsers are in front thus blocking animation.
* Wait up to 60 seconds for animation finish.
*/
// Thread sleep 1000
await condition(find(id("password")).exists(_.isDisplayed), 60)
pwdField(name("password")).value = password
pressKeys("\n")
}

private def oneAccountSignIn(email: String, password: String): Unit = {
emailField(id("email")).value = email
find(id("next")).get.underlying.submit()
pwdField(id("Passwd")).value = password
find(id("signIn")).get.underlying.submit()
}

/**
* Handles the post-sign-in dance of switching Selenium's focus back to the
* main FireCloud window.
* TODO: make this work when there is more than one window
*/
def returnFromSignIn(): Unit = {
/*
* The sign-in popup may go away at any time which could cause any calls
* such as findElement to fail with NullPointerException. Therefore, the
* only safe check we can make is on the number of windows.
*/
try {
await condition (windowHandles.size == 1)
} catch {
case _: TimeoutException =>
/*
* If there is still more than 1 window after 30 seconds, we most likely
* need to approve access to continue.
*/
if (windowHandles.size > 1) {
click on id("submit_approve_access")
await condition (windowHandles.size == 1)
}
}

switch to window(windowHandles.head)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ class PostExportModal(methodNamespace: String, methodName: String)(implicit webD
def stayHere(): Unit = {
cancel()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ class GoogleSignInPopup(implicit webDriver: WebDriver) extends WebBrowser with W
def signIn(email: String, password: String): Unit = {
(id("Email").findElement.isDefined) match {
case true => oneAccountSignIn(email, password)
case false => normalSignIn(email, password)
}
case false => normalSignIn(email, password) }
returnFromSignIn()
}

Expand Down
Loading