Is Page Object Model linking compatible with Cucumber's Gherkin? Is Page Object Model linking compatible with Cucumber's Gherkin? selenium selenium

Is Page Object Model linking compatible with Cucumber's Gherkin?


Ok so having asked numerous dev and test automation experts, it seems the solution is to continue with linking [e.g. WelcomePage welcomePage = loginPage.loginWithValidUser(validUser)] is the way to go.

To persist instance of page objects across steps (e.g. welcomePage in example above) you can use dependency injection tool (creating functionality similar to World extensions in Ruby's implementation of cucumber).

Here is more info:https://cukes.info/docs/reference/java-di

However, most projects will benefit from a Dependency Injection module to organize your code better and to share state between Step Definitions.

More info from SpecFlow (the .net official cucumber implementation):

http://specflow.org/getting-started/beyond-the-basics/

And finally, I have created a whole blog around this area that might help people out, since gherkin/page object interaction is a subject of great interest to me:

http://www.seligmanventures.com/dev-blog/test-automation-page-object-model-with-gherkin


When it comes to most websites (where url's can be used), in my opinion it is best practice to simply use the url instead of an action to get to that same url.

For instance:

# Suggested by OP:driver = Selenium::Webdriver.for :chrome, prefs: prefshomepage = Homepage.new(driver)login = homepage.go_to_loginwelcome = login.log_in_as('dave4429')# My Suggestion:homepage = Url.new('/')login = Url.new('/login')welcome = Url.new('/welcome')

This means that you start from a url instead of having to start at the homepage for every test. You would still have the methods that you suggested, but they would be used in other areas, in order to make sure that the user can access the page through means other than the url.

However, this is not a one stop shop solution. With mobile and desktop applications, your only option may be to go through the home screen, in which case, the method you suggested is definitely the one to go for.

"Page objects themselves should never make verifications or assertions. This is part of your test and should always be within the test’s code, never in an page object." - Selenium HQ

The example I gave was a very basic one, and I would most likely wrap these into modules and classes, to enable coding like this:

google = Project::Pages::Google.newgoogle.search_for('Hello, World!')expect(google.found_result?).to_equal(true)

Edit

In addition to this, you seem to have a misconception about how Cucumber works with Gherkin.

You can have multiple lines of code per step, as the step itself is a description of the actions within the step.

For instance:

Given I am logged in as "dave4429"When I have submitted the "Contact Us" form with the following data:   | dave4429@example.com | David McBlaine | I want to find out more about your Data Protection services, can I talk to a staff member or get a PDF? |Then an email should be sent to "support@example.com" with the details specified

The definition for the "When" may look like this:

When(/^I have submitted the "Contact Us" form with the following data:$/) do |table|  rows = table.raw  row = rows[0]  contact_us.fill_form({email: row[0], username: row[1], message: row[2]})  contact_us.submit_message  expect(browser.title).to_equal("Message Sent!")end

It all depends on how much you break down the steps within the definition.

Edit #2

It's also clear to me that you want to do method chaining, something in the way of contact_us.fill_form({email: row[0], username: row[1], message: row[2]}).submit_message, which again, isn't out of the question while using the techniques that I'm suggesting, but the question of whether this chaining should be for each individual page, or whether everything should be included in one class or module, can only be answered by your needs.

It's just my opinion that this would put too much into a single class, and that breaking down that class will allow for more control to be given to the testers, and less redundant code will be written.


Another option I have seen recently would be to store the Page Object instances as Static variables that can be accessed from any class?