【问题标题】:Protractor element(by.css('id_name')).getText() causes browser to waitProtractor element(by.css('id_name')).getText() 导致浏览器等待
【发布时间】:2026-01-13 04:35:01
【问题描述】:

版本信息

Angular CLI: 6.0.8
Node: 8.11.2
OS: win32 x64
Angular: 6.0.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.3
@angular-devkit/build-angular     0.6.3
@angular-devkit/build-optimizer   0.6.3
@angular-devkit/core              0.6.3
@angular-devkit/schematics        0.6.8
@angular/cdk                      6.1.0
@angular/cli                      6.0.8
@angular/flex-layout              6.0.0-beta.17
@angular/material                 6.1.0
@ngtools/webpack                  6.0.3
@schematics/angular               0.6.8
@schematics/update                0.6.8
rxjs                              6.2.0
typescript                        2.7.2
webpack                           4.8.3

量角器:5.4.0 茉莉花核:2.6.2 茉莉花规格报告器:4.1.0

问题

我想做一个简单的 e2e 测试,在浏览器重定向到页面后检查元素的内部文本。但是,当检查元素内部时,浏览器只是在页面上停留 10 秒,然后给出以下错误:

1) material App should re-route to login page
  - Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
  - ScriptTimeoutError: Timed out waiting for asynchronous Angular tasks to finish after 10 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: htt
ps://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
  While waiting for element with locator - Locator: By(css selector, #globTitle)

Executed 1 of 1 spec (1 FAILED) in 14 secs.
[20:04:24] I/launcher - 0 instance(s) of WebDriver still running
[20:04:24] I/launcher - chrome #01 failed 1 test(s)
[20:04:24] I/launcher - overall: 1 failed spec(s)
[20:04:24] E/launcher - Process exited with error code 1
An unexpected error occured: undefined

这是我的代码: HTML

<div class="main-container">  
    <mat-toolbar [ngStyle]="{'background-color': topBarColor, 'color': 'white'}" class="topbar telative" style = "z-index: 0 !important;">  
        <button mat-icon-button (click)="snav.toggle()" *ngIf = "showbtn" value="sidebarclosed">
             <mat-icon>menu</mat-icon>  
         </button>  
         <span id = "globTitle">Programme Admin Dashboard</span>  
         <span style = "flex: 1 1 auto;"></span>  
         <button mat-raised-button colour = "warn" *ngIf = "showbtn" (click) = "signOut(); snav.close();" style = "margin-right: 20px;">Sign out</button>  
         <img src="assets/images/logo.png" alt="No logo available" style = "height: inherit; margin-bottom: 5px;">  
     </mat-toolbar>  
     <mat-sidenav-container class="example-sidenav-container" [style.marginTop.px]="mobileQuery.matches ? 0 : 0">  
         <mat-sidenav style = "text-align: center;" #snav id="snav" class="dark-sidebar pl-xs" [mode]="mobileQuery.matches ? 'side' : 'over'" fixedTopGap="0" [opened]= false [disableClose]="mobileQuery.matches" >  
             <app-sidebar (click) = "snav.close()"></app-sidebar>  
         </mat-sidenav>  
         <mat-sidenav-content class="page-wrapper">  
             <div class="page-content">  
                 <router-outlet><app-spinner></app-spinner></router-outlet>  
             </div>  
         </mat-sidenav-content>  
         <ng-template #loadingSpinner>  
         <mat-spinner></mat-spinner>  
             <p>Fetching permissions...</p>  
         </ng-template>  
    </mat-sidenav-container>  
</div>

app.po.ts

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

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

  getURIChange(url: string) {  
    const ec = protractor.ExpectedConditions;  
  browser.wait(ec.urlContains(url), 2000);  
  }  
}

app.e2e-spec.ts: (请注意,当我删除最后一行代码时,测试会成功运行。事实上,即使达到 element(by.css('#globTitle')) 也可以正常工作。 但是如果我把它改成element(by.css('#globTitle')).getText(),这就是浏览器等待的地方,我得到上面提到的错误。 从 './app.po' 导入 { AppPage };
从“量角器”导入{浏览器,元素,按};

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

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

  it('should re-route to login page', async () => {  
    console.log('Waiting for angular');  
  await browser.waitForAngularEnabled();  
  console.log('Angular initialized');  
  console.log('Waiting on navigation to page');  
  // page.navigateTo();  
  await browser.get('http://localhost:4201/');  
  console.log('Navigation completed, should be redirected to the login page');  
  page.getURIChange('/login');  
  expect(element(by.css('#globTitle')).getText()).toEqual('Programme Admin Dashboard');  
  });  
});

另外,我不确定这是否会有所帮助,但这是我的量角器配置和业力配置以防万一。 protractor.conf.js: const { SpecReporter } = require('jasmine-spec-reporter');

exports.config = {  
  allScriptsTimeout: 10000,  
  specs: [  
    './e2e/**/*.e2e-spec.ts'  
  ],  
  capabilities: {  
    'browserName': 'chrome'  
  },  
  directConnect: true,  
  baseUrl: 'http://localhost:4200/',  
  framework: 'jasmine',  
  jasmineNodeOpts: {  
    showColors: true,  
  defaultTimeoutInterval: 10000,  
  print: function() {}  
  },  
  onPrepare() {  
    require('ts-node').register({  
      project: 'e2e/tsconfig.e2e.json'  
  });  
  jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));  
  }  
};

karma.conf.js

module.exports = function (config) {  
  config.set({  
    basePath: '',  
  frameworks: ['jasmine', '@angular-devkit/build-angular'],  
  plugins: [  
      require('karma-jasmine'),  
  require('karma-chrome-launcher'),  
  require('karma-jasmine-html-reporter'),  
  require('karma-coverage-istanbul-reporter'),  
  require('@angular-devkit/build-angular/plugins/karma')  
    ],  
  client:{  
      clearContext: false // leave Jasmine Spec Runner output visible in browser  
  },  
  coverageIstanbulReporter: {  
      dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],  
  fixWebpackSourcePaths: true  
  },  
  angularCli: {  
      environment: 'dev'  
  },  
  reporters: ['progress', 'kjhtml'],  
  port: 9876,  
  colors: true,  
  logLevel: config.LOG_INFO,  
  autoWatch: true,  
  browsers: ['Chrome'],  
  customLaunchers: {  
      ChromeNoSandbox: {  
        base: 'Chrome',  
  flags: ['--no-sandbox']  
      }  
    },  
  singleRun: false,  
  });  
};

【问题讨论】:

  • 你执着于等待 Angular 吗?好像 await browser.waitForAngularEnabled(false);如果你能忍受的话,可以解决这个问题。

标签: jasmine protractor angular6 angular-e2e


【解决方案1】:

试试这个:

const el1 =  await $('#globTitle').getText();
expect(el1).toEqual('Programme Admin Dashboard');

getText() 等待一个承诺解决,因此不能像以前那样工作。

【讨论】:

  • 在顶部添加import * as $ from 'jquery'; 并添加您建议的行后,我收到以下错误: (node:11188) UnhandledPromiseRejectionWarning: E​​rror: jQuery requires a window with a document... 另外,我的代码直接来自文档,但仍然无法为我工作,尽管它对其他人有用
  • 您尝试打印 el1 吗?它说什么?
  • 它不允许我打印,因为 jQuery 错误阻止了打字稿被编译
【解决方案2】:

您好,您没有在步骤定义中返回回调。

所以 jasmine 认为您正在执行或等待某些操作发生。但是一旦发生超时,即 10 秒,它就会引发错误

it('should re-route to login page', async (done) => { 
  console.log('Waiting for angular'); 
  await browser.waitForAngularEnabled(); 
  console.log('Angular initialized'); 
  console.log('Waiting on navigation to page'); // page.navigateTo(); 
  await browser.get('http://localhost:4201/'); 
  console.log('Navigation completed, should be redirected to the login page'); 
  page.getURIChange('/login'); 
 Var a = element(by.css('#globTitle');
  Var b = a.getText().then((value)=>{console.log('title is'+value);
return value;}) 

expect(b).toEqual('Programme Admin Dashboard'); done() 
    }); 

【讨论】:

  • 步骤定义?您的意思是在 it 代码块内部吗?另外,我试过 element(by.css('#globTitle')).getText().then((text) => { expect(text).toBe('Programme Admin Dashboard'); });这也不起作用
  • 添加完成就像我在答案中添加的那样。如果需要,增加您的全局超时时间
  • 我已将全局超时时间增加到 100000 毫秒,但错误仍然存​​在。我意识到这个问题似乎发生在几乎所有返回承诺的函数上。 browser.getTitle() 给了我同样的行为。我也尝试了一个 catch 语句,但没有运气。所有的承诺都没有解决
  • 请检查是否在console.log中打印标题