To test our website and react native mobile app, we have created a hybrid framework using webdriver.io and cucumber.io.
We currently have separate feature files for the same functionality on both the web and mobile.
E.g
In Mobile_getMembersDetails.feature
@mobile
Scenario: As a user, I can see the list of members on the home screen
When I am on the home screen
Then I can see the members list on mobile home screen
In the corresponding step implementation is
@when(/^I am on the home screen$/)
public async whenIamOnHomeScreen() {
await mobileLandingPage.clickContinueButton();
await mobileHomePage.clickAllowButton();
expect(await mobileHomePage.isHeaderDisplayed()).toBe(true);
}
@then(/^I should see the members list on mobile home screen$/)
public async thenIshouldSeeMemberslistOnMobileHomeScreen() {
expect(await mobileHomePage.isMemberListIsDisplayed());
}
In Web_getMembersDetails.feature
@web
Scenario: As a user, I can see the list of members on the home page
When I am on the home page
Then I can see the members list on web home page
In the corresponding step implementation is
@when(/^I am on the home page$/)
public async whenIamOnHomePage() {
webHomePage.open();
expect(await webHomePage.isPageLoaded()).toBe(true);
}
@then(/^I can see the members list on web home page$/)
public async thenIshouldSeeMemberslistOnWebHomePage() {
expect(await webHomePage.isMemberListIsDisplayed()).toBe(true);
}
Even though the functionality is the same, the navigation and implementation for web and mobile are different. What is the best way to do this as a single feature file and step? We were thinking of adding @web and @mobile tags, then deciding which type of test to run based on the execution command. However, this Leeds to many if else conditions and steps will become more complex. Or having one feature file is not an good idea ? Thanks
@web @mobile
Scenario: As a user, I can see the list of members on the home page
When I am on the home page
Then I can see the members list on web home page
Proposed step implementation is
@when(/^I am on the home page$/)
public async whenIamOnHomePage() {
if(driver.isMobile()){
await mobileLandingPage.clickContinueButton();
await mobileHomePage.clickAllowButton();
expect(await mobileHomePage.isHeaderDisplayed()).toBe(true);
}else {
webHomePage.open();
expect(await webHomePage.isPageLoaded()).toBe(true);
}
}
@then(/^I can see the members list on web home page$/)
public async thenIshouldSeeMemberslistOnWebHomePage() {
if(driver.isMobile()){
expect(await mobileHomePage.isMemberListIsDisplayed());
}else{
expect(await webHomePage.isMemberListIsDisplayed()).toBe(true);
}
}
2
Answers
Instead of defining a
mobileHomePage
andwebHomePage
would define a singlehomePage
. Then when instantiating thehomePage
you check what kind of web driver you have.Now you only have to check once for each page. E.g:
This does require that
MobileHomePage
andWebHomePage
implement the sameHomePage
interface. So to make yourwhenIamOnHomePage
step possible you’ll have to implement aopenHomePage
that either goes from the mobile landing page, to the home page, or directly opens the web home page. And something similar applies toisPageDisplayed
.The interesting things with this problem is what is the overlap between web and mobile at the feature/scenario level.
If your features and scenarios are mostly abstract enough that the behaviour you are describing is the same on native as on website, then you can think about solutions where the same step calls different implementations. Here you need to decide two things
Then you can run cucumber twice on your CI, once for native and once for website.
If there is alot of behaviour that is specific to native or website then you can either
Finally you can combine solutions you could end up with
With disciplined refactoring the combined solution could work very nicely. Consider the scenario