私の分度器e2eテストは一貫して合格し、失敗しています。
これは、ここで説明するように、非同期のJavaScriptが原因である可能性があります。 分度器:ボタンをクリックした後、ページが完了するのを待つ方法は?。
ただし、ここでは、分度器のテストが自動的に順次/同期的に実行されることが言及されています。 https://github.com/angular/protractor/issues/909
私のテストスクリプト:
describe('Login', function() {
var ptor;
beforeEach(function() {
browser.get('https://127.0.0.1:8443');
ptor = protractor.getInstance();
element(by.id('splash')).click();
browser.ignoreSynchronization = true; // <-- to proceed beyond splash screen
});
describe('with correct email and password', function() {
beforeEach(function() {
element(by.id('email')).sendKeys('[email protected]');
element(by.id('password')).sendKeys('adminpassword');
element(by.id('loginButton')).click();
});
afterEach(function() {
ptor.findElement(by.id('logout')).then(function(elem) {
elem.click();
});
});
it('does not show alert', function() { // <-- sometimes passes, sometimes fails
expect(browser.isElementPresent(by.css('.alert-danger'))).toBe(false);
});
it('changes route to /admin', function() { // <-- sometimes passes, sometimes fails
expect(browser.getCurrentUrl()).toMatch(/\/admin/);
});
});
});
上記の2つのテストでは、 両方のテストに合格します、または 1つまたは両方のテストが失敗する これらのメッセージで:
Failures:
1) Login with correct email and password does not show alert
Message:
NoSuchElementError: no such element
...
==== async task ====
WebDriver.findElement(By.id("logout"))
...
または
Failures:
1) Login with correct email and password changes route to /admin
Message:
NoSuchElementError: no such element
...
==== async task ====
WebDriver.findElement(By.id("logout"))
...
考え/助けていただければ幸いです。
私は以下に基づいて問題を解決することができました:
Avishay のptor.waitForAngular()の追加に関する回答:
ロケーターを使用して要素が見つかりません:by.model()エラー
変化 ブラウザ.get to ptor.get、たとえば Harri Siirak の答えは次のとおりです。
$ resourceを使用すると、分度器がページとの同期を待機してタイムアウトします
juliemr のインスタンス変数であるignoreSynchronizationに関するここのコメントと変更 ブラウザ.ignoreSynchronization = true to ptor.ignoreSynchronization = true:
https://github.com/angular/protractor/issues/49
glepretre の.then()の使用に関する回答:
分度器:ボタンをクリックした後、ページが完了するのを待つ方法は?
元の質問への Nguyen Vu Hoang のコメントで述べたように、私は純粋なAngularアプリを純粋な分度器と考えているものでテストしています(webdriver呼び出しはありません)。この場合、ptor.ignoreSynchronization = trueは必要ないはずですが、何らかの理由で、この設定がないとボタンクリックでテストが続行されません。
私の新しいスペック:
describe('Login', function() {
var ptor;
beforeEach(function() {
ptor = protractor.getInstance();
ptor.ignoreSynchronization = true;
ptor.waitForAngular();
ptor.get('https://127.0.0.1:8443');
ptor.findElement(by.id('splash')).then(function(elem) {
elem.click();
});
});
describe('with correct email and password', function() {
beforeEach(function() {
ptor.findElement(by.id('email')).then(function(elem) {
elem.sendKeys('[email protected]');
});
ptor.findElement(by.id('password')).then(function(elem) {
elem.sendKeys('adminpassword');
});
ptor.findElement(by.id('loginButton')).then(function(elem) {
elem.click();
});
});
afterEach(function() {
ptor.findElement(by.id('logout')).then(function(elem) {
elem.click();
});
});
it('does not show alert', function() {
expect(ptor.isElementPresent(by.css('.alert-danger'))).toBe(false);
});
it('changes route to /admin', function() {
expect(ptor.getCurrentUrl()).toMatch(/\/admin/);
});
});
});
テストをより安定させる別の手法もあります:明示的な待機と予期される条件( docs )。
角張っていないページや、アニメーションが多数含まれているangularアプリケーションに対してテストするときに、期待される条件を使用すると特に便利であることがわかりました。
たとえば、クリックする前に要素がクリック可能になるまで待つことができます。
_var EC = protractor.ExpectedConditions;
var link = element(by.id("mylink"));
browser.wait(EC.elementToBeClickable(link), "10000", "The link is still not clickable");
link.click();
_
以下のような他の組み込みの期待される条件もあります。
presenseOf()
visibilityOf()
alertIsPresent()
textToBePresentInElementValue()
また、カスタムの期待される条件、サンプルユースケースを簡単に記述できます。
combine Expected Conditions を使用してand
、or
およびnot
を使用することもできます。例:
_var urlChanged = function() {
return browser.getCurrentUrl().then(function(url) {
return url != 'http://www.angularjs.org';
});
};
// condition to wait for url to change, title to contain 'foo', and $('abc') element to contain text 'bar'
var condition = EC.and(urlChanged, EC.titleContains('foo'), EC.textToBePresentInElement($('abc'), 'bar'));
$('navButton').click();
browser.wait(condition, 5000); //wait for condition to be true.
_
browser.ignoreSynchronization = true;すべてのテストにグローバルな効果があります。 falseに戻す必要がある場合があるため、分度器はangularがページのレンダリングを完了するのを待ちます。たとえば、2番目のbeforeEach関数の中または前に