Protractor - works well on localhost but remote th

2019-09-03 18:28发布

问题:

When I execute protractor protractor.conf.js --baseUrl=http://localhost:4200/, it works well - fills data, validates elements, etc.

When I try to test exactly the same website via remote URL protractor protractor.conf.js --baseUrl=http://the-same-website.com/, it opens up in browser, logins and all necessary parts are loaded like in localhost but Protractor/Jasmine does not fill/click/validate anything and I get timeout after specified time:

  - Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
      at ontimeout (timers.js:436:11)
      at tryOnTimeout (timers.js:300:5)
      at listOnTimeout (timers.js:263:5)
      at Timer.processTimers (timers.js:223:10)
  - Failed: script timeout: result was not received in 30 seconds
    (Session info: chrome=71.0.3578.98)

There are other threads will similar problems on Stack Overflow - tried browser.ignoreSynchronization = true and Protractor.waitForAngular(false) but then page doesn't load properly and tests fail because elements aren't found.

UPDATE 1

The test below works well on localhost - outputs success or failure depending on h1 but on remote URL it doesn't check anything despite web is loaded:

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

describe('example-test', () => {

  const PATH_TO_TEST = 'specific-path/to/test';

  beforeEach(() => {
    browser.get(PATH_TO_TEST);
  });

  it('should exist header', () => {
    expect(element(by.css('h1')).getText()).toEqual('test');
  });
});

If I add logging, I see output but expect is not executed:

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

describe('example-test', () => {

  const PATH_TO_TEST = 'specific-path/to/test';

  beforeEach(() => {
    browser.get(PATH_TO_TEST);
    console.log('beforeEach');
  });

  it('should exist header', () => {
    expect(element(by.css('h1')).getText()).toEqual('test');
    console.log('test end');
  });
});

Protractor config:

const { SpecReporter } = require('jasmine-spec-reporter');

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

UPDATE 2

If I add browser.sleep and browser.ignoreSynchronization, tests begin to work but then I need to add browser.sleep for every synchronization which doesn't look nice:

beforeEach(() => {
  browser.get('path/to/test');
  browser.sleep(3000);
  browser.ignoreSynchronization = true;
});

It seems that Protractor does not recognize page as fully loaded or as Angular web.

Why Protractor does not validate content despite the page is loaded properly?

回答1:

UPDATED: Completed changed original proposed answer.

This issue could be due to the nature of your login page. If your login is non-angular then you must instruct protractor not to wait for angular to become testable (which it will by default). To do this you can use the browser.waitForAngularEnabled(false) command which it the recommended new way as opposed to the previous browser.ignoreSynchronization = true.

After you have logged into your application you can set your browser.waitForAngularEnabled back to true and the rest of your tests in that spec should behave correctly.

describe('Main', function {
  beforeAll(function () {
      browser.waitForAngularEnabled(false);
      Site.login();
      //after you have successfully logged into you site you can 
      browser.waitForAngularEnabled(true);
  });

  it('should show the main page', function () {
     //Your code
  });
});