2017-06-02 4 views
0

Je suis nouveau sur Angular2 et n'ai pas développé les composants angulaires à tester. Cependant, je suis supposé écrire quelques tests d'interface utilisateur (e2e) mais je ne suis même pas capable de saisir du texte dans un champ de saisie.Test Angular2 + e2e - Ne peut pas être utilisé by.id

Mon problème est que element(by.id('username')).sendKeys('test') ne fonctionne pas. (Pareil avec des éléments de bouton et ainsi de suite)

Je suis sûr que c'est seulement une petite chose mais je ne suis pas capable de savoir ce que c'est.

J'ai la configuration suivante:

  • Proctractor: 5.1.2
  • pilote chrome: 58.0.3029.110
  • OS: Windows NT 6.1.7601 SP1 x86_64

Fichier de spécifications:

import { LoginPage } from './login.po'; 

describe('login tests', function() { 
    let page: LoginPage; 

    beforeEach(() => { 
    page = new LoginPage(); 
    }); 

    it('Demo',() => { 
    page.navigateTo(); 
    page.getUsernameInput().sendKeys('test'); 
    }); 
}); 

page fichier objet:

import { browser, element, by } from 'protractor'; 

export class LoginPage { 
    navigateTo() { 
    return browser.get('/login'); 
    } 

    getParagraphText() { 
    return element(by.class('app-root h1')).getText(); 
    } 

    getUsernameInput() { 
    return element(by.id('username')); 
    } 
} 

Le modèle HTML:

.... 
<div> 
    <input 
    id="username" 
    name="username" 
    ngModel 
    type="text" 
    placeholder="{{something}}" 
    autocomplete="off" 
    class="input-text" 
    required> 
</div> 
... 

Proctractor config

var SpecReporter = require('jasmine-spec-reporter'); 

exports.config = { 
    allScriptsTimeout: 120000, 
    getPageTimeout: 120000, 
    specs: [ 
     './e2e/**/*.e2e-spec.ts' 
    ], 
    capabilities: { 
     'browserName': 'chrome' 
    }, 
    directConnect: true, 
    seleniumAddress: 'http://localhost:4444/wd/hub', 
    baseUrl: 'http://localhost:8001', 
    framework: 'jasmine', 
    jasmineNodeOpts: { 
     showColors: true, 
     defaultTimeoutInterval: 30000, 
     print: function() {} 
    }, 
    useAllAngular2AppRoots: true, 
    beforeLaunch: function() { 
     require('ts-node').register({ 
     project: 'e2e' 
     }); 
    }, 
    onPrepare: function() { 
     jasmine.getEnv().addReporter(new SpecReporter()); 
    } 
}; 

Toute aide est fortement appréciée.

EDIT: Aucune des solutions n'a fonctionné dans mon cas. J'ai fini par utiliser browser.driver.findElement(by.id('username')); au lieu de element(by.id('username')); Ceci est insatisfaisant parce que je ne comprends toujours pas pourquoi cela ne fonctionne pas. Je serais reconnaissant si quelqu'un pourrait me donner un indice ou une explication.

+0

Quelle est l'erreur que vous obtenez? Veuillez ajouter l'erreur que vous obtenez. – demouser123

+0

Par erreur, je voulais dire que le texte ne sera pas inséré. Mais je ne vois aucun message d'erreur sur la console. – Vetemi

Répondre

0

Je crois que cela est dû à votre méthode getUsernameInput() retournant pas le localisateur dans ce cas. Selon la documentation de Protractor,

La fonction element() renvoie un objet ElementFinder. ElementFinder sait comment localiser l'élément DOM en utilisant le locator que vous avez transmis en tant que paramètre, mais cela n'a pas encore été fait. Il ne contactera pas le navigateur tant qu'une méthode d'action n'a pas été appelée.

Vous pouvez essayer ce code modifié

getUsernameInput() { 
     element(by.id('username')).sendKeys('text'); 
    } 
    } 

puis en utilisant

it('Demo',() => { 
     page.navigateTo(); 
     page.getUsernameInput(); 
    }); 
}); 

Aussi, je ne suis pas sûr que votre getText() renverrait le texte, parce que getText() retourne une promesse qui vous devriez résoudre.Cela a été expliqué here.

+0

Oh oui, le getText() n'est pas utilisé. Il a été généré et j'ai juste oublié de le supprimer. Même avec votre changement, cela ne fonctionne malheureusement pas. Toute autre supposition, peut-être? – Vetemi

2

Je pense que votre problème est le timing.

Qu'advient-il si vous faites:

it('Demo',() => { 
    // wait for page to change to /login 
    return page.navigateTo().then(() => { 
     // then look for user input and write 'test' 
     return page.getUsernameInput().sendKeys('test'); 
    });  
}); 

Edit:

me étrange sons que browser.driver.findElement(by.id('username')) œuvres depuis element(by.id('username')) devraient être équivalentes. J'utilise une classe d'aide pour beaucoup d'interactions avec le navigateur, peut-être vaut le coup.

Snippets-je utiliser pour trouver l'élément et l'envoi de frappes:

public static async getElement(locator: By | Function, waitMs?: number): Promise<ElementFinder | any> { 

    await BrowserHelper.waitForVisibilityOf(locator, waitMs | 1000); 

    return element(locator); 
} 

public static sendKeys(locator: By | Function, keys: string, clear?: boolean, waitMs?: number): Promise<void> { 
    return BrowserHelper.getElement(locator, waitMs).then((element: ElementFinder) => { 
     if (!clear) { 
      return element; 
     } 

     return element.clear().then(() => element); 
    }).then((element: ElementFinder) => { 
     return element.sendKeys(keys) 
    }); 
} 

public static async waitForVisibilityOf(locator: By | Function, waitMs?: number): Promise<any> { 
    await browser.wait(EC.presenceOf(element(locator)), waitMs || 5000).then(() => { 
     // visible 
    }, (error) => { 
     console.error('timeout at waitForVisibilityOf', locator, error); 
    }); 
} 
+0

Ce n'est pas le problème. Ça ne marche toujours pas malheureusement. Voir mon édition pour plus d'informations. – Vetemi

+0

Etrange, et toujours pas de sortie indiquant ce qui se passe avec la version 'element()'? Essayez peut-être d'ajouter le drapeau '--verbose' lorsque vous exécutez le rapporteur. – cYrixmorten