web-dev-qa-db-fra.com

Protractor + chrome driver: l'élément n'est pas cliquable au point

Bonjour, j’ai du mal à faire passer un test de rapporteur de base.

Ma configuration:

  • J'utilise requirejs, alors je lance angular en utilisant angular.bootstrap (), pas l'attribut ng-app. Selon les rapporteurs de rapporteur, cela n’est pas pris en charge immédiatement, mais semble fonctionner correctement pour les tests qui ne nécessitent pas de cliquer.
  • Rapporteur conf.json:

    "use strict";
    exports.config = {
        specs: '../E2ETests/**/*.js',
        chromeOnly: true,
        getPageTimeout: 30000,
        allScriptsTimeout: 30000
    }
    
  • J'utilise des plug-ins tiers de jQuery que j'emballe dans des directives, je suppose que cela pourrait faire partie du problème.

Le test:

"use strict";
describe('When clicking should add stuff', function () {
    var ptor;
    beforeEach(function () {
        browser.get('https://localhost/myApp');
        ptor = protractor.getInstance();
    });
    it('add stuff', function () {
        // If I comment this, the test pass. 
        element(by.id('add-stuff-button')).click();
        // This does not matter fails on the line above..
        expect(browser.getTitle()).toBeDefined();
    });
});

L'erreur:  

UnknownError: unknown error: Element is not clickable at point (720, 881). Other element would         receive the click: <div class="col-md-5 col-md-offset-5">...</div>
(Session info: chrome=37.0.2062.124)
(Driver info: chromedriver=2.10.267521,platform=Windows NT 6.1 SP1 x86_64)

Pensées

Le chromedriver trouve le bouton, car si je change l'identifiant, il se plaint qu'aucun élément ne soit trouvé. Je pense donc que le problème est que le bouton bouge de sa position initiale. Comme la fonction element (***) doit attendre que angular soit faite, je soupçonne que ce sont les plugins tiers qui pourraient interférer, car ils pourraient ne pas utiliser les données récupérées par l'API angular, etc. remplit et déplace des choses autour. 

Une idée de ce qu'on peut faire? Si le problème est lié au tiers, puis-je dire en quelque sorte à Angular que des activités de tiers sont en cours et ensuite, plus tard?

Thx Br Twd

29
twDuke

Vous devriez définir la taille de la fenêtre dans votre fichier de configuration

onPrepare: function() {
  browser.manage().window().setSize(1600, 1000);
}
24
Gal Margalit

Suivre a bien fonctionné pour moi:

browser.actions().mouseMove(element).click();

Edit: Si ci-dessus ne fonctionne pas, essayez aussi d’enchaîner la méthode perform () (j’ai eu ceci comme suggestion d’édition, je ne l’ai pas testée mais quelqu'un pourrait la vérifier et commenter)

browser.actions().mouseMove(element).click().perform();
18
Aman Gupta

Cela se produit si la fenêtre chromée est trop petite, essayez d'ajouter à l'intérieur de beforeEach 

browser.driver.manage().window().setSize(1280, 1024);
12
originof

Ou utilisez simplement la classe Actions:

browser.actions().mouseMove(elem).click().perform();
11
Raul Huluban

Peut-être que cela n’est pas applicable dans votre cas, mais j’ai rencontré le même problème et, sur la base de la réponse de Milena , j’ai cherché un autre élément obscurcissant mon bouton (dans mon cas, un menu déroulant en haut à droite de mon écran).

Il semble s'agir du message de notification connecté au navigateur envoyé par browsersync, lancé par Gulp. Le message a disparu peu de temps après, mais après mon appel à onClick ().

Pour supprimer la notification, dans mon fichier gulp, j'ai ajouté le paramètre notify: false lors de l'initialisation de browsersync:

browserSync.init(files, {
    server: {
        baseDir: "dist",
        index: "index.html"
    },
    notify: false
});
4
Emmanuel P.

Je résous ce problème en utilisant le temps de sommeil du navigateur. 

browser.driver.sleep(3000)

avant de donner le clic

3
Anik Saha

Avait le même problème, mais n'était pas lié à la taille de la fenêtre, mais a dû attendre que ngAnimation se termine.

J'ai donc dû attendre que l'élément soit cliquable avec.

    const msg = 'Waiting for animation timeout after 1s';
    const EC  = new protractor.ProtractorExpectedConditions();
    await browser.wait(EC.elementToBeClickable(model.elements.button.checkCompliance), 1000, `${msg} panel`);
    await model.elements.button.checkCompliance.click();

@ note - J'utilise async/wait noeud 8. Vous pouvez tout aussi bien le convertir en Promises . Utiliser également ProtractorExpectedConditions au lieu de ExpectedConditionsvoir la documentation

3
fredtma

J'ai eu la même erreur et le simple fait d'ajuster la taille de l'écran ne m'a pas résolu le problème. 

Après une inspection plus poussée, il sembla qu'un autre élément masquait le bouton. Le test au sélénium échoua car le bouton n'était pas (et ne pouvait pas être cliqué). C’est peut-être pour cette raison que l’ajustement de la taille de l’écran le corrige pour certains?

Ce qui réparait la mine enlevait l'autre élément (et en ajustait ensuite le positionnement).

2
Milena

Sinon, vous pouvez essayer ceci:

this.setScrollPage = function (element) {

    function execScroll() {
        return browser.executeScript('arguments[0].scrollIntoView()',
            element.getWebElement())
    }

    browser.wait(execScroll, 5000);
    element.click();
};
1
Tayguara Dias Reis

De la réponse de Gal Malgarit

Vous devriez définir la taille de la fenêtre dans votre fichier de configuration

onPrepare: function() {
  browser.manage().window().setSize(1600, 800);
}

Si cela ne fonctionne toujours pas, vous devez faire défiler jusqu'à l'emplacement de l'élément

browser.executeScript('window.scrollTo(720, 881);');
element(by.id('add-stuff-button')).click();
0
patronaviera

Vous pouvez également essayer de désactiver tous les outils de débogage que vous utilisez. J'utilisais Laravel et Debugbar et devais définir APP_DEBUG sur false.

0
xtrahelp.com

Notez que cela a parfois été provoqué par une barre de navigation supérieure ou une barre d'avertissement de cookie/de cookie inférieure couvrant l'élément. Avec l'angle 2, lorsque vous cliquez dessus, l'élément défile jusqu'à ce que l'élément ne soit que sur la page. Cela signifie que lors du défilement vers le bas pour cliquer sur quelque chose, s'il y a une navigation en bas, cela obstruera le clic. De même, lorsque vous faites défiler l'écran vers le haut, il peut être couvert par la navigation du haut. 

Pour l'instant, pour utiliser le défilement, j'utilise les éléments suivants: 

browser.refresh();
browser.driver.sleep(3000);

Je me suis assuré d’avoir retiré la barre du bas en cliquant dessus pour la fermer avant le début du test. 

0
Sam

Vous pouvez définir la résolution d'écran souhaitée dans votre fichier de configuration de rapporteur (par exemple, protractor.conf.js ou config.js) pour un comportement de test cohérent.

Par exemple avec le navigateur Chrome:

exports.config = {
  specs: [
    // ...
  ],
  capabilities: {
    browserName: 'chrome',
    chromeOptions: {
      args: [
        '--window-size=1600,900',
        '--headless'
      ]
    }
  }
  // ...
}

Des explications

  • L'argument window-size lancera Chrome avec une fenêtre de 1600 par 900.
  • headless lancera Chrome sans tête, vous permettant ainsi d’exécuter vos tests avec la taille de fenêtre spécifiée (1600 x 900) même si la résolution de votre écran est inférieure à celle.

Vous voudrez peut-être avoir deux configurations, une pour les développeurs (sans mode sans tête) qui ont toujours un écran haute résolution et une pour les serveurs de build (mode sans tête) où la résolution de l'écran est parfois un mystère et peut être inférieure à celle de votre application/test conçu pour. Les fichiers de configuration de rapporteur sont en javascript et peuvent être étendus pour éviter la duplication de code.

0
Jerome