4

I'm writing some protractor tests for our application. There is one place where is non-angular page as iframe in angular page.

Problem: I'm unable to map fields from non-angular page in Page Object object and use them in right time in my test specs.

Notes:

  • I tried write Page Object as object (var DamagePage: {}) and as function (var DamagePage = function() {}) too. Both works bad in this situation.
  • Calling fields from non-angular page in spec works obviously fine, but I want to have it in Page Object for correct project organization.
  • I have set browser.driver.ignoreSynchronization = true;

Here is my spec>

'use strict';

var DamagePage = require('../../pages/case/CaseDamagePage.po.js');

describe('Damage selection - ', function() {

  var damagePage = new DamagePage();

  it('Switch to iFrame',function(){
      browser.driver.switchTo().frame('padIframe');
  });

  it('Open a zone', function() {
      browser.driver.findElement(by.id('30_0_79')).click();
      browser.sleep(2000);
  });

  it('Select a part', function () {
      browser.driver.findElement(by.id('32_0_201')).click();
      browser.sleep(3000);
  });

  it('Put I on it with 5 WU', function() {
      // Click I
      damagePage.leftMenuButtons.I.button.click();
  });

And here is my PageObject (actually as function)>

'use strict';

var CaseInterface = require('./CaseInterface.js');

var DamagePage = function() {

  // LEFT-SITE MENU BUTTONS
  this.leftMenuButtons = {
      I: {
          button: browser.driver.findElement(by.id('operation-button-I'))
      },
      E: {
          button: element(by.id('operation-button-E')),
          mutation: element(by.id('operation-button-mutation-E'))
      }
  };
};

module.exports = DamagePage;

In the spec all works fine until it comes to 'Put I on it with 5 WU' step. In this configuration, I got error immediately after protractor start:

C:\Users\xxx\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\atoms\error.js:108 var template = new Error(this.message); ^ NoSuchElementError: no such element: Unable to locate element: {"method":"id","selector":"operation-button-I"} (Session info: chrome=47.0.2526.106) (Driver info: chromedriver=2.19.346078 (6f1f0cde889532d48ce8242342d0b84f94b114a1),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 22 milliseconds For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html

Well, it is thanks to "browser.driver.findElement" syntax in Page Object. When I change it to "element", protractor starts correctly and run until 'Put I on it with 5 WU' step. Here it throws:

Failed: Error while waiting for Protractor to sync with the page: "angular could not be found on the window"

user2377585
  • 67
  • 1
  • 2
  • 9

1 Answers1

2

I got error immediately after protractor start

This is because of where you initialize the Page Object - Protractor initializes your Page Object very early, when gathering the specs. You need to initialize the page object inside the beforeEach():

describe('Damage selection - ', function() {
    var damagePage;

    beforeEach(function () {
       damagePage = new DamagePage();
    });

    // ...
});

Or, directly inside the it():

it('Put I on it with 5 WU', function() {
    var damagePage = new DamagePage();

    // Click I
    damagePage.leftMenuButtons.I.button.click();
});
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks for your reply. I tried BeforeEach function and protractor start and run until 'Put I...' step with message "Failed: Error while waiting for Protractor to sync with the page: "angular could not be found on the window"" – user2377585 Jan 22 '16 at 16:23
  • @user2377585 okay, should not you tweak the `ignoreSynchronization` flag, since this is a non-angular frame?.. – alecxe Jan 22 '16 at 16:25
  • Well, I tried both true and false ignoreSynchronization, and comment it out too. Test with every setting ends with the same error "Failed: Error while waiting for Protractor to sync with the page: "angular could not be found on the window"" – user2377585 Jan 22 '16 at 16:30
  • @user2377585 thanks, what would happen if you switch all the related locators to `browser.driver.FindElement`? – alecxe Jan 22 '16 at 16:34
  • Well it works, but now I got `Failed: no such element: Unable to locate element: {"method":"id","selector":"operation-button-I"}` while in first it "Switch to iFrame". This happened due to BeforeEach function. I have to initialize DamagePage, but I need switch to iFrame too. It seems like I have to move `damagePage = new DamagePage();` into every one IT except "Switch to iFrame" - functional but not too much ideal solution. – user2377585 Jan 25 '16 at 10:00
  • @user2377585 could you try wrapping the `leftMenuButtons` into a `getLeftMenuButtons()` function and call it inside the `it()`? I suspect the problem is that it is an object and the fields are evaluated too early. Thanks. – alecxe Jan 25 '16 at 12:38
  • Yes, it works! So all fields in page object must be functions. Thanks! – user2377585 Jan 25 '16 at 13:03