简体   繁体   中英

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       | first@somewhere.com   |                | Fail           |
    | Second    | User       | second@somewhere.com  | .              | Fail           |
    | Third     | User       | third@somewhere.com   | toofew         | Fail           |
    | Fourth    | User       | fourth@somewhere.com  | weakpassword   | Fail           |
    | Fifth     | User       | fifth@somewhere.com   | MissingNumber  | Fail           |
    | Sixth     | User       | sixth@somewhere.com   | m1ssingc4pital | Fail           |
    | seventh   | User       | seventh@somewhere.com | 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?)

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) { }

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
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM