Reputation: 427
What's the best way to fill in a web form with lots of text inputs if the project is using Cucumber and the Page Object Model?
For example, let's say the feature file is something like this:
Scenario: As someone who wants to sign up
When I visit the homepage
And I click on the Register button
And I enter my firstname
And I enter my surname
And I enter my email address
And I enter a new password
And I re-enter my new password
And I agree to the terms and conditions
And I click the Submit button
Then I should see a welcome page
I understand that the step defs generated by Cucumber would generate a separate method for each of these, which is fine. Would I then have to implement each of these steps in the "RegistrationPage" in its own method? What I'm trying to get at is: is there a way to implement a kind of "fillInform()" method instead of separate methods in the RegistrationPage?
EDIT:
The question I asked is probably wrong (I was trying to keep it short). My objective is to be able to do something like this:
Scenario Outline: As someone who wants to sign up
When I visit the homepage
And I click on the Register button
And I enter my "<firstname>" in the firstname input
And I enter my "<surname>" in the surname input
And I enter my "<emailaddress>" in the email input
And I enter my "<password>" in the password input
And I enter my "<password>" in the password confirmation input
And I agree to the terms and conditions
And I click the Submit button
Then I expect the registration to "<ExpectedResult>"
Examples:
| firstname | surname | emailaddress | password | ExpectedResult |
| First | User | [email protected] | | Fail |
| Second | User | [email protected] | . | Fail |
| Third | User | [email protected] | toofew | Fail |
| Fourth | User | [email protected] | weakpassword | Fail |
| Fifth | User | [email protected] | MissingNumber | Fail |
| Sixth | User | [email protected] | m1ssingc4pital | Fail |
| seventh | User | [email protected] | CapsAndNumb3r | Pass |
Given such a scenario outline, would it still be possible to fill in the registration form using a single method? Something I have thought of (and I'm not sure what the implications of this would be) is to:
@When("^I enter \"([^\"]*)\" in the firstname input$")
public void enterFirstname(String firstname) {
registrationPage.firstname = firstname;
}
and then, when the test presses the "Submit" button:
@When("^I click the Submit button$")
public void clickSubmitButton() {
registrationPage.fillInForm();
registrationPage.clickJoinButton();
}
However, doing it this way just doesn't "feel right" to me (although I could be mistaken - perhaps it's acceptable?)
Upvotes: 3
Views: 5511
Reputation: 9058
You can use a combination of datatable and scenario outline to accomplish this.
..
..
And Enter form details
| firstname | surname |.........| password | reppwd |
| <fname> | <sname> |.........| <pwd> | <rpwd> |
..
..
Examples:
| fname | sname |.........| pwd | rpwd |
| Name1 | Title1 |.........| pwd1 | pwd1 |
| Name2 | Title2 |.........| pwd2 | pwd2 |
| Name3 | Title3 |.........| pwd3 | pwd3 |
You can use the raw datatable to get the data in the step definition.
public void enterDetails(DataTable tab) { }
Or create a dataobject(UserDetails) using the headers of datatable (firstname, surname...) as instance variables.
public void enterDetails(List<UserDetails> tab) { }
Upvotes: 6
Reputation: 13712
1) Feature file
Scenario: As someone who wants to sign up
When I visit the homepage
And I click on the Register button
And I fill the register form
And I agree to the terms and conditions
And I click the Submit button
Then I should see a welcome page
2) Step definition
Then("^I fill the register form$", () -> {
registrationPage.fillForm(user);
})
3) RegistrationPage
public fillForm(User user) {
driver.findElement(xxx).sendKeys(user.firstName);
driver.findElement(xxx).sendKeys(user.surName);
...
}
There is a issue need to resolve, how to pass down the value for argument user
for fillForm()
, you need to consider your code framework, how it store the user data, how it get the user data. The solution depeneds on self code framework. Not have a unify solution.
1) Solution example when this scenario only test one user:
Scenario: As someone who wants to sign up
When I visit the homepage
And I click on the Register button
And I fill the register form with user <userId>
And I agree to the terms and conditions
And I click the Submit button
Then I should see a welcome page
HashMap<String, User> users = xxxxx;
Then("^I fill the register form with user (.+)?$", (String userId) -> {
registrationPage.fillForm(users.get(userId));
})
2) Solution example when this scenario need to test multiple user:
Scenario Outlines: As someone who wants to sign up
When I visit the homepage
And I register user <userId>
Examples:
| userId |
| 001 |
| 002 |
| ... |
HashMap<String, User> users = xxxxx;
Then("^I register user (.+)?$", (String userId) -> {
registrationPage.registerUser(users.get(userId));
// inside registerUser(), should includes the whole proceduce:
// click register button
// fill form
// agree to the terms
// click submit button
// verify see welcome page
})
Upvotes: 3