Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Page Object Pattern in React Component Tests #830

Open
tomoyukikashiro opened this issue Aug 14, 2022 · 0 comments
Open

Use Page Object Pattern in React Component Tests #830

tomoyukikashiro opened this issue Aug 14, 2022 · 0 comments

Comments

@tomoyukikashiro
Copy link
Owner


date: 2022-08-13
title: Use Page Object Pattern in React Component Tests
summary: It might be worthy to use page object pattern in react component as well as E2E tests to make tests readability and maintainability better.
slug: page-object-pattern-in-react-component-tests
lang: en-US
tags:


My understanding is that readability and maintainability are domains which should be put high priority in software tests. To achieve this, using Page Object Pattern might be a good help not only in E2E tests but also React Component tests.

What is the Page Object Pattern

https://webdriver.io/docs/pageobjects/

Page Object Pattern is one of the software programming principle which encapsulate page manipulation logic that tend to harm readability and maintainability in software tests.

Software test involves two kinds of cods below.

  • test code : e.g. Shows error messages when invalid email is typed in form.
  • manipulation code to reproduce test situation : e.g. Shows page then type email

Page Object Pattern aims to move the latter codes to page class, which is called Page Object, to help software engineers read and write the former codes easily.

The example of Page Object Pattern

Let's see https://webdriver.io/docs/pageobjects/

// Page class has E2E test instance which comes from test library such as selenium.
import Page from './page'

class LoginPage extends Page {

    // Defines some functions to manipulate page to reproduce test situation.
    get username () { return $('#username') }
    get password () { return $('#password') }
    get submitBtn () { return $('form button[type="submit"]') }
    get flash () { return $('#flash') }
    get headerLinks () { return $$('#header a') }

    async open () {
        await super.open('login')
    }

    async submit () {
        await this.submitBtn.click()
    }

}

export default new LoginPage()

By using this page instance to prepare test cases, we can make test codes simple.

it('should deny access with wrong creds', async () => {
    await LoginPage.open()
    await LoginPage.username.setValue('foo')
    await LoginPage.password.setValue('bar')
    await LoginPage.submit()

    await expect(LoginPage.flash).toHaveText('Your username is invalid!')
})

How to use Page Object Pattern in React Component tests

import type { ComponentProps } from "react";
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import LoginForm from "./LoginForm";

type Props = ComponentProps<typeof LoginForm>

const setup = (props): Props => {
  const { getByRole, getByLabelText, getByText } = render(<LoginForm {...props} />);
  return {
    typeEmail: (email: string) => userEvent.type(getByLabelText("email"), email),
    getByText,
    submit: () => userEvent.click(getByRole("button"))
  };
};


it("When email typed is invalid, shows error message.", () => {
  const utils = setup();
  utils.typeEmail("invalidemail");
  utils.submit();

  expect(utils.getByText("Email is not correct.")). toBeInTheDocument();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant