量角器无法检测元素

时间:2019-01-31 11:09:24

标签: angular selenium-webdriver protractor e2e-testing

我具有被所述用户之后才显示的组件中记录...

  <div data-e2e="profile-dd" class="profile-dropdown" [ngClass]="{'white-text': router.url.search('profile') === -1, 'black-text': router.url.search('profile') !== -1}" (click)="showProfile = !showProfile">
    <img data-e2e="profile-img" class="circular-photo" alt="person_dp" [src]="person.profile_photo" />
    <i class="cm" [ngClass]="{'cm-arrow-down': !showProfile, 'cm-arrow-up': showProfile}"></i>
  </div>

我想要当用户登录到该元件检查存在。在我的.po.ts文件中,我有一个函数可以将该元素获取为:

export class AppPage {
  ...
  ...

  async checkIfUserLoggedIn() {
    return await element(by.css('[data-e2e="profile-dd"]')).isPresent();
  }
}

在我的.e2e-spec.ts文件中,我编写了一个测试,但失败了,该测试记录了Expected false to be true.


describe('YOP Login page tests', function () {
    let loginPage: LoginPage;
    let appPage: AppPage;

    beforeEach(() => {
        loginPage = new LoginPage();
        appPage = new AppPage();
    });

    ...
    ...

    it('User should be logged in successfully', () => {
        appPage.checkIfUserLoggedIn().then(res => {
            expect<any>(res).toBe(true);
        });
    });

});

任何人可以帮助我,我要去哪里错了?

PS-我在其下方编写了另一个随机测试。它工作,这意味着浏览器未崩溃。

2 个答案:

答案 0 :(得分:0)

好吧,您看到isPresent()是要获取元素的当前状态,这可能不是您的情况。您要登录,然后应该出现element,但是我们不知道确切的时间。您的问题是,量角器在Angular在登录后显示元素之前进行了检查。在这里应使用ExpectedConditions。您正在寻找visibilityOf子句。

 async checkIfUserLoggedIn() {
    var EC = protractor.ExpectedConditions;
    await browser.wait(EC.visibilityOf(element(by.css('[data-e2e="profile-dd"]'))), 5000, 'Element did not appear after login');
 }

以下代码将等待5秒钟,您的元素才会显示。如果元素在5秒钟内出现或失败并显示指定的消息,将会更早解决。

这里是如何使用它

it('User should be logged in successfully', async () => {
    await appPage.checkIfUserLoggedIn();
});

答案 1 :(得分:0)

看来您仍然需要等待appPage.checkIfUserLoggedIn()。为此,您需要在量角器配置文件(如下所示)中设置SELENIUM_PROMISE_MANAGER: false。除此之外,您至少应位于节点8上。

it('User should be logged in successfully', async () => {
    expect(await appPage.checkIfUserLoggedIn()).toBe(true);
});

为什么需要等待...

因此,在您的checkIfUserLoggedIn方法中:

  1. element(by.css('[data-e2e="profile-dd"]')).isPresent()返回一个webdriver.promise.Promise<boolean>。等待这一点可以解决这个诺言,您将获得布尔值。
  2. 由于checkIfUserLoggedIn是一个异步函数,因此它现在成为本机Promise。因此,您的返回类型为本地Promise<boolean>
  3. 在您的it块中,您需要将其更改为async,并按期望将await返回Promise<boolean>

更新:添加有关量角器配置和tsconfig的信息。

量角器配置

您需要从量角器配置文件中关闭控制流:

 exports.config = {
   SELENIUM_PROMIMSE_MANAGER: false,  // turns off the control flow
   // Other parts of your config including capabilities, etc.
   // Below is an example of the rest of the configuration file:
   capabilities: { browserName: 'chrome' },
   specs: [ 'e2e/**/*.e2e-spec.ts' ],
   seleniumAddress: 'http://127.0.0.1:4444/wd/hub'
 }

tsconfig.json

浏览此StackOverflow问题的注释和其他部分,似乎您正在使用polyfills来实现promise。如果更新到节点8,则应该能够使用本机Promises。您的tsconfig可能只是:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2017",
    "types: ["jasmine", "jasminewd2", "node"]
    // Other parts of your tsconfig
  }
}

注意:在量角器6中,控制流已删除,因此迁移到异步/等待是准备下一个版本的好主意。由于控制流已删除,因此jasminewd2也将被删除。这意味着tsconfig类型将仅为["jasmine", "node"]