DEV Community

Cover image for Modular Import in Page Objects
Dmitrii Bormotov
Dmitrii Bormotov

Posted on

Modular Import in Page Objects

Ahoy, mate!

This topic may be useful for test automation engineers who'd like to make their code look better!

I wrote about Page Objects in Cypress earlier - take a look if you haven't already! Modular import isn't a new thing, and if you haven't heard about it and its profits before - you can find more in an article from @fahadaminshovon :

Source code of project from this article on GitHub: https://github.com/bormando/swag-tests/pull/2/files

In short, it structures your code better, let's see how...


How it was

It's pretty usual, when during a test you navigate from one page to another. In that case you need to import all pages involved into that spec file:

import AuthPage from '../pages/auth.page'
import ProductsPage from '../pages/products.page'
Enter fullscreen mode Exit fullscreen mode

But what if that test involves more pages? And usually spec file combines multiple test suites - which probably means A LOT of pages if we combine all tests.


How to improve it

We can declare a folder that contains page objects to be a module (and technically it is). To do that, simply add index.js file in the (page) folder.

This file is an "entry point" of our "pages" module. You say there what would you like to export from the module, like this:

export * from './auth.page'
export * from './products.page'
export * from './cart.page'
Enter fullscreen mode Exit fullscreen mode

* means everything

If you'd like to export ready-to-use page instances in Cypress with this structure, you'll need to rewrite exports as well:

import Page from './page'
...

export const CartPage = new class extends Page {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Code above says that new instance of the class will be created when you'll import this page in your tests. It's a bit different than default export like this:

export default new CartPage()
Enter fullscreen mode Exit fullscreen mode

default export lets you set any name you like when you import whatever you do, while the other construction sets a specific name for the instance that you export.

How it looks now

Now you don't call every page file to import the page you need:

import {AuthPage, ProductsPage} from '../pages'
Enter fullscreen mode Exit fullscreen mode

pages folder is a module now and you name objects you'd like to get from there that were exported.

This practice may be used with other modules as well, like Page Elements.

Top comments (1)

Collapse
 
blue_crow_3af7ba766fed799 profile image
Blue Crow

A great article helped me a lot in my case. thank you.
By the way, I have one question. Why can't we use export default new CartPage() in this case without rewriting exports as you mentioned? I've tried and got an error in the test file import Module '"../../pageObjects"' has no exported member 'Login'.ts(2305). Not sure why it's happening. If you can explain that, much appreciated. Thank you!