typescriptcucumberwebdriver-ioautomation-testing

How to use same cucumber steps for both mobile and web tests when testing the same functionality?


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

Solution

  • Instead of defining a mobileHomePage and webHomePage would define a single homePage. Then when instantiating the homePage you check what kind of web driver you have.

    if(driver.isMobile())
      homePage = new MobileHomePage(driver);
    else
      homePage = new WebHomePage(driver);
    

    Now you only have to check once for each page. E.g:

    @when(/^I am on the home page$/)
    public async whenIamOnHomePage() {
      homePage.openHomePage();
      expect(await homePage.isPageDisplayed()).toBe(true);
    }
    
    @then(/^I can see the members list on web home page$/)
    public async thenIshouldSeeMemberslistOnWebHomePage() {
        expect(await homePage.isMemberListIsDisplayed()).toBe(true);
    }
    

    This does require that MobileHomePage and WebHomePage implement the same HomePage interface. So to make your whenIamOnHomePage step possible you'll have to implement a openHomePage that either goes from the mobile landing page, to the home page, or directly opens the web home page. And something similar applies to isPageDisplayed.