繁体   English   中英

Angular2 + e2e测试-不能使用by.id

[英]Angular2+ e2e testing - Cannot use by.id

我是Angular2的新手,还没有开发要测试的Angular组件。 但是,我应该编写一些UI(e2e)测试,但是我什至无法在输入字段中输入文本。

我的问题是element(by.id('username')).sendKeys('test')无法正常工作。 (与Button元素相同,依此类推)

我确定这只是一件小事,但我无法找出它是什么。

我有以下配置:

  • 量角器 :5.1.2
  • chrome驱动程序 :58.0.3029.110
  • 作业系统 :Windows NT 6.1.7601 SP1 x86_64

规格文件:

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

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

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

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

页面对象文件:

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'));
  }
}

HTML模板:

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

量角器配置

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());
    }
};

非常感谢您的帮助。

编辑:在我的情况下没有解决方案。 我最终使用了browser.driver.findElement(by.id('username')); 而不是element(by.id('username')); 这是不令人满意的,因为我仍然不明白为什么这不起作用。 如果有人可以给我提示或解释,我将不胜感激。

我认为您的问题是时机。

如果您这样做会发生什么:

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');
    });    
});

编辑:

由于element(by.id('username'))应该等效,所以browser.driver.findElement(by.id('username'))起作用对我来说听起来很奇怪。

我在许多浏览器交互中都使用了一个辅助类,也许值得一试。

我用于查找元素和发送击键的代码片段:

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);
    });
}

我相信这是由于在这种情况下,您的getUsernameInput()方法未返回定位符。 根据量角器文档,

element()函数返回一个ElementFinder对象。 ElementFinder知道如何使用您作为参数传入的定位器来定位DOM元素,但实际上尚未这样做。 在调用动作方法之前,它不会与浏览器联系。

您可以尝试此修改后的代码

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

然后使用

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

另外,我不确定您的getText()是否会返回文本,因为getText()返回的Promise必须解决。 这已经在这里解释

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM