如何使用量角器定位角应用程序之外的元素?

时间:2017-11-22 06:33:04

标签: angular protractor e2e-testing

我有一个在Angular app bootstraps之前播放的介绍元素。

<!-- need to target div below -->
<div id="intro"></div>
<!-- still bootstraping -->
<app-root></app-root>

我正在使用Angular-cli中提供的以下量角器规范

describe('my App', () => {
  let page: AppPage;

  beforeEach(() => {
    page = new AppPage(); // default from angular cli
  });

  it(`should provide an intro div`, () => {
    page.navigateTo();
    const introDiv = element(by.id('intro'));
    expect(introDiv.isPresent()).toBe(true); // reports as false in protractor test
  });
});

我能够使用上面相同的'it'函数来定位Angular App中的元素,为什么它不能在Angular应用程序之外工作?我如何在index.html中定位元素?

更新

我已经做了进一步的测试,并想在问题中记录这个仅供参考:

上面没有提到,我实际上有角度删除了介绍div,因为它是全屏覆盖。

由于引用了Ernst Zwingli提供的Protractor文档,它告诉我Protractor会在每次WebDriver操作之前自动应用browser.waitForAngular()命令。

所以上面的测试试图以intro div为目标找不到它,因为它在寻找它之后进行了角度引导并删除了div。

我在index.html中创建了一个临时div,没有任何接触。它只是element(by.id('find-me'))可用,即使它在Angular的应用程序之外。

<div id="find-me"></div>

it(`is available after angular bootstraps and can be targeted with element()`, () => {
    const findMeDiv = element(by.id('find-me'));
    expect(findMeDiv.isPresent()).toBe(true);
  });

我终于可以使用browser.waitForAngularEnabled(false)来定位介绍div,因为它在Angular bootstraps之前可用。虽然这只等待$ http和$ timeouts,但似乎足以能够在bootstrap之前定位div。我不确定它是否完全取消browser.waitForAngular()

(waitForAngular()的差异等待呈现,http,超时,而waitForAngularEnabled()仅关注 http 超时 - 虽然名称相似性可能暗示waitForAngularEnabled(false)完全取消waitForAngular(),例如还包括呈现,但未在文档中指定。)

<div id="intro"></div>

// Works
  it(`Found to be available if I use browser.waitForAngularEnabled(false) since div is removed when Angular is ready`, () => {
    browser.waitForAngularEnabled(false);
    const introDiv = element(by.id('intro'));
    expect(introDiv.isPresent()).toBe(true);
  });

所以基本上Ernst Zwingli和Xotabu4都提供了很好的洞察力,因为我需要browser.waitForAngularEnabled(false);并且可以使用element()函数来访问div。

1 个答案:

答案 0 :(得分:2)

您基本上应该将该部分视为non-angular,并使用Selenium WebDriver-methods查找元素。

因此,element(by.id('intro'))使用browser.driver.findElement(by.id('intro'))使用JavaScript / Vanilla browser.driver代替Protractor browser,而不是browser使用expect(),因此可以在外面工作任何角度范围。

但是,您需要放弃element(locator) - 语句,因为量角器ElementArrayFinder代表findElement(),而WebDriver方法代表getWebElement(),{{1}和类似的,直接表示WebElement(因此它们会立即执行元素搜索,并且在代码需要真正的WebElement之前不要等待它)。 Read about here

所以在你的情况下,使用findElement你得到一个WebDriver-Error,因为该元素不存在,或者你得到了WebElement,因为它就在那里(不需要进一步检查存在)。

Here the Selenium-Documentationhere a GitHub, that explains the use of Protractor in Non-Angular

<强> Bytheway

如果整页是非角色的,则需要使用browser.waitForAngularEnabled(false)关闭Protractor ControlFlow(这是ignoreSynchronization = true之前的版本,但不再使用它了。)

如果只有部分页面是非角色的,您可能不需要关闭Protractor,但您可能需要明确处理同步执行(尝试和错误)

<强>更新

由于我得到的评论,我觉得有必要链接到一些进一步的信息,这进一步证明了我的观点(因为Protractor&lt;&gt; Vanilla):