Vanessa Deagan
Vanessa Deagan

Reputation: 427

Cucumber Selenium - fill in web form

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

Answers (2)

Grasshopper
Grasshopper

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

yong
yong

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

Related Questions