I am trying to get familiar with Geb. I’m trying to run it from inside Grails, but that shouldn’t matter at all since my question here is specific to Geb.
I have the following test
directory structure:
myapp/
<lots of stuff here>
test/
functional/
GebConfig.groovy
LogInLogOutSpec.groovy
pages/
LogInPage.groovy
DashboardPage.groovy
Where LoginPage.groovy
is (obviously) the login page, and where DashboardPage
is where you should be redirected to after logging in successfully. In reality I have security filters in place that will check to see if the URL you are trying to access requires authentication. If so, they redirect you to the login page, and after successful login, redirect you again to the URL you were trying to access.
For good measure, here’s the HTML that comprises my login page (again, this is Grails, so a GSP file is dynamically converted into HTML at runtime):
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<form action=“/myapp/auth/signIn" method="post">
<input type="hidden" name="targetUri" value="/dashboard" />
<table>
<tbody>
<tr>
<td>Username:</td>
<td><input type="text" name="username" value="" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" value="" /></td>
</tr>
<tr>
<td />
<td><input type="submit" value="Sign in" /></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
So I need a Geb test that:
Furthermore:
HtmlUnitDriver
, but correct me if I’m wrong)GebConfig
file or some external parameter (perhaps as env vars or runtime args supplied to the Grails command line). Essentially I don’t want to store username/password in test code.My best attempt so far:
GebConfig.groovy
:
driver = {
// Again, or Firefox
ChromeProfile profile = new ChromeProfile()
Driver driverInstance = new ChromeDriver(profile)
driverInstace.manage().window().maximize()
driverInstance
}
baseNavigatorWaiting = true
atCheckWaiting = true
// Need to inject from some external process somehow, but make these
// available to test specs somehow.
username = System.env("USERNAME")
password = System.env("PASSWORD")
LogInLogOutSpec.groovy
:
import geb.spock.GerbReportingSpec
import spock.lang.*
import pages.*
@Stepwise
class LogInLogOutSpec extends GebReportingSpec {
String username
String password
/*
* Attempt to go to user dashboard, and confirm you are instead
* redirected to the login page. Login with good credentials,
* and verify you are now logged in and at the dashboard.
*/
def "successful login redirects to dashboard page"() {
when:
to DashboardPage
then:
"Login".equals($(".page-header").text())
when:
$("#login-form input[name=username]").value(username)
$("#login-form input[name=password]").value(password)
then:
"Dashboard".equals($(".page-header").text())
}
}
I think I'm close, but this is obviously wrong. Any ideas where I’m going awry? Thanks!
You should modularize your test code. You should use
In your code example you have a dashboard page, but no login page object. You should also think about a login modul if all your pages have the possibility to login or at least provide the possibility to detect the login state. See this SO answer for a modul definition. What is missing here is a function to determine the login state.For another implementation look at the AuthModule and the login test spec of the Geb examples.
To the login credentials: I think you did a good job having the credentials in the environment. This works fine on a developer machine and also on the build server.
For testing with different browsers: geb-example-gradle is a gradle sample project with a GebConfig and a build.gradle. This allows you to switch browser as argument to gradle:
./gradlew chromeTest
./gradlew firefoxTest
./gradlew phantomJsTest
This also answers your last question: a good headless browser I like to use is phantomJs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With