Objeto Página (pageObject)

Cuando te encuentras haciendo test para una aplicación que no tiene módulos testables y tienes que hacerlo contra la interfaz directamente, es muy probable que te encuentres ante esta situación:

// scoreBoard.spec.js

// [...]

it('should save score after answer a question', function () {
    startGame();
    selectOption(0);
    submitAnswer();
    addPlayerName(players[1]);
    saveScore();
    expectScoreToContainsMinusOne();
});

function startGame() {
    let startButton = document.getElementById('start-button');
    startButton.click();
}

function selectOption(optionId) {
    let answer = document.getElementById(optionId);
    answer.click();
    expect(answer.checked).toBeTruthy();
}

// [...]

Y luego en otro test lo siguiente:

// game.spec.js

// [...]

it('should start the game, answer a question and change the score', function () {
    startGame();

    selectOption(0);
    submitAnswer();

    expectScoreToBeDifferentFromTheBeginning();
});

function startGame() {
    let startButton = document.getElementById('start-button');
    startButton.click();
}

function selectOption(optionId) {
    let answer = document.getElementById(optionId);
    answer.click();
    expect(answer.checked).toBeTruthy();
}

// [...]

Estámos repitiendo los mismos métodos startGame() y selectOption() y eso es algo que no nos gusta en el código limpio. Por ello es que existe el PageObject model. Este está formado por funciones que trabajan directamente con la interfaz. De esta manera podemos usar todos las funciones manera unificada con el mismo comportamiento.

Extraer al PageObject

Creamos nuestro nuevo fichero donde guardar este modulo que hemos decidido extraer y ponemos las funcionalidades que queremos.

// pageObject.js

export default function pageObject() {

    function startGame() {
        let startButton = document.getElementById('start-button');
        startButton.click();
    }

    function selectOption(optionId) {
        let answer = document.getElementById(optionId);
        answer.click();
        expect(answer.checked).toBeTruthy();
    }

    // [...]

    return {
        startGame,
        selectOption
    };
};

Ahora solo tendremos que importarlo donde lo usábamos anteriormente

// game.spec.js
import gamePageObject from '../src/pageObject';

// [...]

let pageObject = gamepageObject();

it('should start the game, answer a question and change the score', function () {
    pageObject.startGame();

    pageObject.selectOption(0);
    submitAnswer();

    expectScoreToBeDifferentFromTheBeginning();
});

function startGame() {
    let startButton = document.getElementById('start-button');
    startButton.click();
}

function selectOption(optionId) {
    let answer = document.getElementById(optionId);
    answer.click();
    expect(answer.checked).toBeTruthy();
}

// [...]

De igual forma podemos sacar submitAnswer() si lo vemos necesario.

References