Seitenobjekt, asynchrone Befehle in Nightwatch

Nach Artikel der letzten Woche, Ich setze meine Erkundung von Nightwatch mit den Objektseiten und der Umsetzung von Befehlen fort.

Machen wir da weiter, wo wir mit dem aufgehört haben Projekt Nightwatch-Boilerplate, die Sie bereits fertig mit den Themen dieses Artikels auf der Branche finden können Seitenobjekt-Assertion-Befehl.
Beginnen wir damit, dem Stammverzeichnis der Konfigurationsdatei die Pfade zu den Ordnern hinzuzufügen (die wir zuvor erstellt haben), damit Nightwatch jeden Teil finden kann:

[...]
"page_objects_path": "nw/pages",
"custom_commands_path" : ["nw/commands"],
"custom_assertions_path" : ["nw/assertions"],
[...]

Und gehen wir direkt zum Page-Objekt

Seitenobjekt

Zur Erinnerung: Das Seitenobjektmuster definiert eine Abstraktion, die es ermöglicht, einem Teil der Seite ein Objekt zuzuordnen, das sie steuert. Dies ermöglicht unter anderem, dass CSS-Selektoren nicht wiederholt werden, und macht die Tests viel besser lesbar, indem Geschäftsmethoden (Bsp.: browser.page.google().search()) anstelle von technischen Methoden (Bsp.: […] browser. click('button[name=btnG]')[…]).
In der Praxis erstellen wir eine Datei nw/pages/google.js Beschreibung des Seitenobjekts für die Google-Suchseite:

module.exports = {
    elements: {
        searchInput: 'input[type=text]',
        searchBtn: 'button[name=btnG]'
    },
    commands: [{
        fillInSearchInput () {
            this
                .waitForElementVisible('body')
                .setValue('@searchInput', this.api.globals.searchTerm);
            return this.api;
        },
        submit () {
            this
                .waitForElementVisible('@searchBtn')
                .click('@searchBtn')
                .api.pause(1000);
            return this.api;
        }
    }]
};

Der erste Teil, „ Element “, erstellt Aliase für CSS-Selektoren, während der zweite Teil, „ Befehl “, die Erstellung der später in unseren Tests verwendeten Geschäftsmethoden ermöglicht. Sie werden feststellen, dass in den Methoden Aliase (z. B. „@searchInput“) verwendet werden, um die Wiederholung von Selektoren zu vermeiden und somit das Fehlerrisiko zu reduzieren.

Tipps: Ich für meinen Teil gebe in den Befehlen lieber 'this.api' zurück, weil 'this.api' in den Tests dem Parameter 'browser' entspricht. Durch die Rückgabe können wir also die Aufrufe verschiedener Seitenobjekte verketten.

Der Test nw/tests/researchOnGoogle.test.js sieht nun folgendermaßen aus:

module.exports = {
    'Search on google': (browser) => {
        browser
            .init()
            .page.google().fillInSearchInput()
            .page.google().submit()
            .assert.containsText('#main', browser.globals.movieName)
            .end();
    },
    after: (browser) => {
        browser.end();
    }
};

Das ist doch viel verständlicher, oder? Dank unserer google.js- Datei im Page-Object-Ordner haben wir Zugriff auf eine Google- Methode , die es uns ermöglicht, das gleichnamige Page-Object zu verwenden und Operationen auf der Seite auf eine lesbarere Weise als zuvor durchzuführen (siehe: vorherige Version ).

Befehl

In diesem Teil werde ich erklären, wie man mithilfe des Prototyps komplexere Befehle erstellt. Dieses Befehlsformat ermöglicht unter anderem die Verwaltung von Asynchronitäten. Wenn Ihr Bedarf relativ einfach und synchron ist, bleiben Sie auf dem einfaches Format sichtbar auf dem Dokument.
Wie bei einem Seitenobjekt müssen Sie zum Erstellen eines Befehls eine Datei in dem dafür vorgesehenen Verzeichnis erstellen. Lassen Sie uns die Datei erstellen nw/commands/longCommand.js mit diesem Inhalt:

const util = require('util');
const events = require('events');
const LONG_TIME = 2000;
function Cmd() {
    events.EventEmitter.call(this);
}
util.inherits(Cmd, events.EventEmitter);
Cmd.prototype.command = function () {
    setTimeout(() => this.emit('complete'), LONG_TIME);
    return this;
};
module.exports = Cmd;

Ein Befehl ist also in Nightwatch ein Prototyp, der von ihm erbt EreignisEmitter Knoten und der eine Methode enthält 'Befehl'.
Um Nightwatch zu signalisieren, dass dieser Befehl ausgeführt wurde, müssen wir das Ereignis 'gesamten ', und damit es verkettbar ist, geben wir zurück 'fehlen uns die Worte.'. Einmal in den Test integriert, erhalten wir diese endgültige Version:

module.exports = {
    'Search on google': (browser) => {
        browser
            .init()
            .longCommand()
            .page.google().fillInSearchInput()
            .page.google().submit()
            .assert.containsText('#main', browser.globals.movieName)
            .end();
    },
    after: (browser) => {
        browser.end();
    }
};

Fazit

Mit diesem Artikel, gekoppelt mit vorherige zum gleichen Thema, sind Sie jetzt bereit, effektive, lesbare und einfach zu wartende Akzeptanztests zu schreiben und gleichzeitig die Ausführungszeit zu minimieren.
Matthew Breton CTO bei JS Republik
[separator type=““ size=““ icon=“star“] [actionbox color=“default“ title=““ description=“JS-REPUBLIC ist ein auf JavaScript-Entwicklung spezialisiertes Dienstleistungsunternehmen. Wir sind ein anerkanntes Ausbildungszentrum. Alle unsere technischen Schulungen finden Sie auf unserer Partnerseite für Schulungen“ btn_label=“Unser Training“ btn_link=“http://training.ux-republic.com“ btn_color=“primary“ btn_size=“big“ btn_icon=“star“ btn_external ="1"]