web-dev-qa-db-fra.com

Comment corriger le nombre d'éléments correspondants dans Nightwatch?

J'essaie de tester si une application todo a le bon nombre d'éléments.

Les documents semblent traiter presque exclusivement d'éléments uniques, j'ai donc dû utiliser les fonctions du protocole de sélénium. Serait-ce la bonne façon de tester le nombre de sélecteurs correspondants (dans ce cas, vérifier la présence de 2 éléments li)?

client.elements('css selector','#todo-list li', function (result) {
    client.assert.equal(result.value.length, 2);
});

Cela fonctionne dans mon test, mais je ne savais pas s'il y avait des problèmes autour de l'utilisation d'un rappel pour cela. Je ne sais pas non plus pourquoi Nightwatch n'a pas de fonctions d'assistance traitant de plus d'un élément.

31
Tev

J'ai trouvé la solution très élégante suivante dans un modèle VueJS. Il montre comment ajouter un assertion personnalisée dans Nightwatch qui compte le nombre d'éléments renvoyés par un sélecteur. Voir http://nightwatchjs.org/guide#writing-custom-assertions pour plus de détails sur la façon d'écrire des assertions personnalisées dans Nightwatch.

Une fois installé, l'utilisation est aussi simple que:

browser.assert.elementCount('#todo-list li', 2)

Le plugin:

// A custom Nightwatch assertion.
// the name of the method is the filename.
// can be used in tests like this:
//
//   browser.assert.elementCount(selector, count)
//
// for how to write custom assertions see
// http://nightwatchjs.org/guide#writing-custom-assertions
exports.assertion = function (selector, count) {
  this.message = 'Testing if element <' + selector + '> has count: ' + count;
  this.expected = count;
  this.pass = function (val) {
    return val === this.expected;
  }
  this.value = function (res) {
    return res.value;
  }
  this.command = function (cb) {
    var self = this;
    return this.api.execute(function (selector) {
      return document.querySelectorAll(selector).length;
    }, [selector], function (res) {
      cb.call(self, res);
    });
  }
}

Ce code a été ajouté à vuejs-templates par yyx9908 en 2016. Le crédit complet revient donc à yyx9908 .

13
Chris K

Juste pour vous rassurer, je fais une chose similaire lorsque vous essayez de saisir tous les éléments correspondants, par exemple:

    browser.elements("xpath","//ul[@name='timesList']/h6", function(result){
        els = result.value;
        var i = 0;
        els.forEach(function(el, j, elz){
            browser.elementIdText(el.ELEMENT, function(text) {
                dates[i] = text.value;
                i++;
            });
        });
    });
8
Madison Haynie

Alternativement, si vous voulez être sûr que le nombre d'éléments n existe, vous pouvez utiliser une combinaison de :nth-of-type/:nth-child sélecteurs et nightwatch expect.

Par exemple, si vous souhaitez tester si #foo a neuf enfants directs:

function(browser) {
  browser
    .url('http://example.com')
    .expect.element('#foo > *:nth-child(9)').to.be.present;
  browser.end();
}

Ou si #bar a trois enfants directs article:

function(browser) {
  browser
    .url('http://example.com')
    .expect.element('#bar > article:nth-of-type(3)').to.be.present;
  browser.end();
}
7
zgreen

J'ai adapté réponse de Chris K pour prendre en charge les expressions XPath en utilisant la méthode intégrée this.api.elements:

exports.assertion = function elementCount(selector, count) {
  this.message = 'Testing if element <' + selector + '> has count: ' + count

  this.expected = count

  this.pass = function pass(val) {
    return val === this.expected
  }

  this.value = function value(res) {
    return res.value.length
  }

  this.command = function command(callback) {
    return this.api.elements(this.client.locateStrategy, selector, callback)
  }
}

Pour les instructions d'utilisation et les crédits voir sa réponse

2
Tom McKenzie

Et si vous aimez un peu de TypeScript, voici une assertion qui confirmera le nombre d'éléments:

import { NightwatchCallbackResult, NightwatchAssertion, NightwatchAPI } from "nightwatch";

module.exports.assertion = function (selector: string, count: number, description?: string) {

    this.message = description || `Testing if element <${selector}> has count: ${count}`;
    this.expected = count;

    this.pass = (value: number) => value === this.expected;

    this.value = (result: number) => result;

    this.command = (callback: (result: number) => void): NightwatchAPI => {

        const self: NightwatchAssertion = this;

        return self.api.elements(this.client.locateStrategy, selector, (result: NightwatchCallbackResult) => {
            callback(result.value.length);
        });
    }

}

Utilisez comme ceci:

browser.assert.elementCount('body', 1, 'There is only one body element');
0
Zymotik

Vous pouvez utiliser expect.elements (<selector>). count () :

  browser.expect.elements('div').count.to.equal(10);
  browser.expect.elements('p').count.to.not.equal(1);
0
mrroot5