artofcode.info

The beauty of coding!

Reflection for hybrid testing framework with cucumber

Author Avatar steti 11 Dec 2018

After a couple of time I manage to create a Selenium hybrid testing framework base on java reflection functional.

In this post I will explain the base principles of this framework and all pluses and minuses. Let’s begin in our journey.

Based on my experience a good testing framework base on UI functional testing an using Selenium Web Driver have a module with POJO elements witch represents web pages of the testing project, usually this POJO contains and implementation of some basic functional, like insert data to input or click a button. But not in my case I used this time POJO just to declare Web Elements of the page. So a simple page of the project will look like below:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class HomePage1 extends AbstractPageObject {

    public HomePage1(WebDriver driver) {

        super(driver);

    }

 

    @FindBy(xpath = "//*[@id=\"page-wrapper\"]/main/section[1]/div/h1")

    private WebElement pageTitle;

 

    @FindBy(xpath = "//*[@id=\"main-nav\"]/div/ul/li[4]/ul/li[1]/a")

    private WebElement partnerCollegesNavButton;

 

    @Override

    public boolean isInitialized() {

        boolean value = false;

        try {

            value = pageTitle.isDisplayed();

        } catch (Exception e) {

            System.out.println("Page is not initialized");

        }

        return value;

    }

}

 

So I have the page name and the name of web elements, in this case I think to use java reflection for re-usability of the code. Created two generic methods:

  • getWebElementByObjectAndName – return a web element from Object, Object in our case is representation of web page in framework,
  • getPageObjectByPageName – return page representation name.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

public WebElement getWebElementByObjectAndName(Object object, String fieldName) {

    WebElement webElement = null;

    Class<?> validationClass = object.getClass();

    Field[] fields = validationClass.getDeclaredFields();

    for (Field field : fields) {

        if (field.getType() == WebElement.class) {

            field.setAccessible(true);

            if (field.getName().equals(fieldName)) {

                try {

                    webElement = (WebElement) field.get(object);

                } catch (IllegalAccessException e) {

                    e.printStackTrace();

                }

 

            }

 

        }

    }

    return webElement;

}

 

public AbstractPageObject getPageObjectByPageName(PageNames pageNames, WebDriver driver) throws Exception {

    Class<?> c = Class.forName("com.pages.pageObjects." + pageNames.name());

    Constructor<?> cons = c.getConstructor(WebDriver.class);

    return (AbstractPageObject) cons.newInstance(driver);

}

 

And use this methods in steps then click or insert data in a web element, we will have two methods with will be used a lot of time. Implementation is below!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

@When("^user clicks on '(.*)' from current page$")

public void userClicksOnSimpleFileDownloadFromCurrentPage(String webElement) {

    AbstractPageObject currentPage = (AbstractPageObject) scenarioContext.getData(PageKeys.CURRENT_PAGE);

    WebElement foundElement = getWebElementByObjectAndName(currentPage, webElement);

    foundElement.click();

    makeScreenshot((String) scenarioContext.getData(PageKeys.SCENARIO_NAME), (WebDriver) scenarioContext.getData(PageKeys.OPEN_DRIVER));

    scenarioContext.save(PageKeys.LAST_CLICKED, foundElement);

}

 

@When("^user inserts following data in current page$")

public void userInsertsFollowingDataInCurrentPage(List<ItemList> dataTableValues) {

    WebDriver webDriver = (WebDriver) scenarioContext.getData(PageKeys.OPEN_DRIVER);

    AbstractPage currentPage = (AbstractPage) scenarioContext.getData(PageKeys.CURRENT_PAGE);

    for (ItemList itemList : dataTableValues) {

        WebElement webElement = getWebElementByObjectAndName(currentPage, itemList.getFieldName());

        webElement.clear();

        if (itemList.getFieldValue().contains("%s")) {

            String userTestEmail = String.format(itemList.getFieldValue(), LocalDateTime.now().toLocalTime().toSecondOfDay());

            scenarioContext.save(PageKeys.TEST_EMAIL, userTestEmail);

            webElement.sendKeys(userTestEmail);

            highLighterMethod(webDriver, webElement);

            makeScreenshot((String) scenarioContext.getData(PageKeys.SCENARIO_NAME), webDriver);

        } else {

            webElement.sendKeys(itemList.getFieldValue());

            highLighterMethod(webDriver, webElement);

            makeScreenshot((String) scenarioContext.getData(PageKeys.SCENARIO_NAME), webDriver);

        }

    }

}

And example of cucumber scenarios look like this:

1

2

3

4

5

6

And page 'HomePage' is displayed

  And user inserts following data in current page

    | fieldName | fieldValue     |

    | email    | Ivan@Cazlov.com |

    | password | Ivan1234@      |

  And user clicks on 'continueButton' from current page

And important step is to save the current page to have corresponding object of page to return our web element.Code below:

1

2

3

4

5

6

7

8

9

10

11

Cucumber: And page 'HomePage' is displayed

 

Java:

@Then("^page '(.*)' is displayed$")

public void pageIsDisplayed(PageNames pageNames) throws Exception {

    WebDriver driver = (WebDriver) scenarioContext.getData(PageKeys.OPEN_DRIVER);

    AbstractPageObject object = getPageObjectByPageName(pageNames, driver);

    await().atMost(DEFAULT_TIMEOUT, SECONDS).until(() -> object.isInitialized());

    assertTrue("Page object " + pageNames.name() + " is displayed", object.isInitialized());

    scenarioContext.save(PageKeys.CURRENT_PAGE, object);

}

Hope this will help you to re use your code and to implement this type of framework in your experience.

I case of some question don't hesitate to write a comment, I will answer all the questions.

 

 

Frequently Asked Questions

Not necessarily. While it can make code harder to follow, in test frameworks it provides the flexibility needed for generic page object management.

How to Cite This Article

APA Format: steti. (2018). Reflection for hybrid testing framework with cucumber. Retrieved from https://artofcode.info/posts/reflection-for-hybrid-testing-framework-with-cucumber
MLA Format: steti. "Reflection for hybrid testing framework with cucumber." Steti.info, 11 Dec 2018. https://artofcode.info/posts/reflection-for-hybrid-testing-framework-with-cucumber
Chicago Format: steti. "Reflection for hybrid testing framework with cucumber." Steti.info. December 11, 2018. https://artofcode.info/posts/reflection-for-hybrid-testing-framework-with-cucumber
Back to Posts